概要: このチュートリアルでは、TypeScriptにおける型ガードを使用して、変数の型を絞り込む方法を学びます。
型ガードを使用すると、条件ブロック内で変数の型を絞り込むことができます。
typeof
次の例を見てみましょう。
type alphanumeric = string | number;
function add(a: alphanumeric, b: alphanumeric) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
throw new Error('Invalid arguments. Both arguments must be either numbers or strings.');
}
Code language: TypeScript (typescript)
仕組み
- まず、文字列または数値のいずれかを保持できる
alphanumeric
型を定義します。 - 次に、
alphanumeric
型の2つの変数a
とb
を加算する関数を宣言します。 - 次に、
typeof
演算子を使用して、両方の引数の型が数値であるかどうかを確認します。もしそうであれば、+
演算子を使用して引数の合計を計算します。 - その後、
typeof
演算子を使用して、両方の引数の型が文字列であるかどうかを確認します。もしそうであれば、2つの引数を連結します。 - 最後に、引数が数値でも文字列でもない場合はエラーをスローします。
この例では、TypeScriptは条件ブロックでのtypeof
演算子の使用法を認識しています。次のif
ブロック内では、TypeScriptはa
とb
が数値であることを認識します。
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
Code language: TypeScript (typescript)
同様に、次のif
ブロックでは、TypeScriptはa
とb
を文字列として扱い、したがってそれらを1つに連結することができます。
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
Code language: TypeScript (typescript)
instanceof
typeof
演算子と同様に、TypeScriptはinstanceof
演算子の使用法も認識しています。例:
class Customer {
isCreditAllowed(): boolean {
// ...
return true;
}
}
class Supplier {
isInShortList(): boolean {
// ...
return true;
}
}
type BusinessPartner = Customer | Supplier;
function signContract(partner: BusinessPartner) : string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
}
if (partner instanceof Supplier) {
message = partner.isInShortList() ? 'Sign a new contract the supplier' : 'Need to evaluate further';
}
return message;
}
Code language: TypeScript (typescript)
仕組み
- まず、
Customer
クラスとSupplier
クラスを宣言します。
次に、Customer
とSupplier
の共用体型である型エイリアスBusinessPartner
を作成します。 - 3番目に、
BusinessPartner
型のパラメータを受け取る関数signContract()
を宣言します。 - 最後に、パートナーが
Customer
またはSupplier
のインスタンスであるかどうかを確認し、それぞれのロジックを提供します。
次のif
ブロック内では、TypeScriptは、instanceof
演算子のため、パートナーがCustomer
型のインスタンスであることを認識します。
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
}
Code language: TypeScript (typescript)
同様に、TypeScriptは、次のif
ブロック内でパートナーがSupplier
のインスタンスであることを認識します。
if (partner instanceof Supplier) {
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
Code language: TypeScript (typescript)
if文で1つの型が絞り込まれると、TypeScriptはelse
文の中ではそれがその型ではなく、別の型であることを認識します。例:
function signContract(partner: BusinessPartner) : string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
return message;
}
Code language: TypeScript (typescript)
in
in
演算子は、オブジェクトのプロパティの存在を安全にチェックします。型ガードとしても使用できます。例:
function signContract(partner: BusinessPartner) : string {
let message: string;
if ('isCreditAllowed' in partner) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList() ? 'Sign a new contract the supplier ' : 'Need to evaluate further';
}
return message;
}
Code language: TypeScript (typescript)
ユーザー定義型ガード
ユーザー定義型ガードを使用すると、型ガードを定義したり、関数を使用する際にTypeScriptが型を推論するのに役立ちます。
ユーザー定義型ガード関数は、単にarg is aType
を返す関数です。例:
function isCustomer(partner: any): partner is Customer {
return partner instanceof Customer;
}
Code language: TypeScript (typescript)
この例では、isCustomer()
はユーザー定義の型ガード関数です。これで、次のように使用できます。
function signContract(partner: BusinessPartner): string {
let message: string;
if (isCustomer(partner)) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
return message;
}
Code language: TypeScript (typescript)
まとめ
- 型ガードは、条件ブロック内で変数の型を絞り込みます。
- 条件ブロックで型ガードを実装するには、
typeof
演算子とinstanceof
演算子を使用します。