TypeScriptでオプションパラメータを駆使する:型ガード、デフォルト値、レストパラメータ、オーバーロード、アサーション
TypeScript におけるオプションパラメータの有無を確認する方法
オプションパラメータの有無を確認するには、以下の2つの方法があります。
型ガードを使用する
型ガードを使用して、パラメータの型を調べることができます。型ガードは、条件式を使用してパラメータの型を絞り込むものです。
function greet(name?: string) {
if (name !== undefined) {
console.log(`Hello, ${name}!`);
} else {
console.log('Hello, world!');
}
}
greet(); // Hello, world!
greet('Taro'); // Hello, Taro!
上記の例では、name
パラメータの型を string | undefined
にしています。型ガードを使用して、name
が undefined
でないかどうかを確認しています。
デフォルト値を使用する
オプションパラメータにデフォルト値を設定することができます。デフォルト値は、パラメータが省略された場合に割り当てられる値です。
function greet(name = 'world') {
console.log(`Hello, ${name}!`);
}
greet(); // Hello, world!
greet('Taro'); // Hello, Taro!
上記の例では、name
パラメータにデフォルト値として 'world'
を設定しています。パラメータが省略された場合、'world'
が name
に割り当てられます。
どちらの方法を使用するかは、状況によって異なります。型ガードを使用すると、パラメータの型に関するより詳細な情報を得ることができますが、コードが冗長になる可能性があります。デフォルト値を使用すると、コードが簡潔になりますが、パラメータの型に関する情報が失われます。
上記以外にも、オプションパラメータの有無を確認する方法があります。
in
演算子を使用するtypeof
演算子を使用する
// 型ガードを使用する例
function greet(name?: string) {
if (name !== undefined) {
console.log(`Hello, ${name}!`);
} else {
console.log('Hello, world!');
}
}
greet(); // Hello, world!
greet('Taro'); // Hello, Taro!
// デフォルト値を使用する例
function greet(name = 'world') {
console.log(`Hello, ${name}!`);
}
greet(); // Hello, world!
greet('Taro'); // Hello, Taro!
// typeof 演算子を使用する例
function greet(name?: string) {
if (typeof name === 'string') {
console.log(`Hello, ${name}!`);
} else {
console.log('Hello, world!');
}
}
greet(); // Hello, world!
greet('Taro'); // Hello, Taro!
// in 演算子を使用する例
function greet(obj: { name?: string }) {
if ('name' in obj) {
console.log(`Hello, ${obj.name}!`);
} else {
console.log('Hello, world!');
}
}
greet({}); // Hello, world!
greet({ name: 'Taro' }); // Hello, Taro!
- 4つ目の例は、
in
演算子を使用してobj
オブジェクトにname
プロパティが存在するかどうかを確認しています。 - 3つ目の例は、
typeof
演算子を使用してname
パラメータが文字列かどうかを確認しています。 - 2つ目の例は、デフォルト値を使用して
name
パラメータが省略されたかどうかを確認しています。 - 1つ目の例は、型ガードを使用して
name
パラメータがundefined
でないかどうかを確認しています。
レストパラメータを使用すると、関数に渡されたすべての引数を配列として取得できます。オプションパラメータを含む、すべての引数を取得できます。
function greet(message: string, ...args: string[]) {
console.log(message);
for (const arg of args) {
console.log(arg);
}
}
greet('Hello', 'Taro', 'Hanako');
// Hello
// Taro
// Hanako
上記の例では、greet
関数は message
という必須パラメータと、...args
というレストパラメータを持っています。greet
関数に渡されたすべての引数は args
配列に格納されます。オプションパラメータが渡されたかどうかを確認するには、args
配列の長さを確認できます。
オーバーロードを使用する
オーバーロードを使用すると、同じ名前の関数を複数の定義を持つことができます。各定義は、異なるパラメータリストを持つことができます。オプションパラメータの有無に応じて、異なる関数を呼び出すことができます。
function greet(name?: string): void;
function greet(obj: { name: string }): void;
function greet(nameOrObj: string | { name: string }) {
if (typeof nameOrObj === 'string') {
console.log(`Hello, ${nameOrObj}!`);
} else {
console.log(`Hello, ${nameOrObj.name}!`);
}
}
greet('Taro'); // Hello, Taro!
greet({ name: 'Hanako' }); // Hello, Hanako!
上記の例では、greet
関数は2つの定義を持っています。1つ目の定義はオプションの name
パラメータを持つ関数です。2つ目の定義は、name
プロパティを持つオブジェクトを持つ関数です。greet
関数に渡された引数に応じて、適切な関数が呼び出されます。
アサーションを使用する
アサーションを使用すると、コンパイラに特定の条件がtrueであることを保証できます。オプションパラメータが渡されたかどうかを保証するために使用できます。
function greet(name?: string) {
const assertedName = name as string; // アサーション
console.log(`Hello, ${assertedName}!`);
}
greet('Taro'); // Hello, Taro!
greet(); // エラー: 'name' は 'string' ではない可能性があります
上記の例では、greet
関数はオプションの name
パラメータを持っています。name
パラメータが渡された場合、as
キーワードを使用して name
を string
型にアサートします。アサーションにより、コンパイラは name
が string
型であることを保証します。greet
関数に name
パラメータが渡されなかった場合、コンパイラはエラーをスローします。
注意事項
上記の方法を使用する際には、以下の点に注意する必要があります。
- アサーションを使用する場合は、アサーションが常にtrueであることを確認する必要があります。アサーションがfalseである場合、コンパイラはエラーをスローしません。
- オーバーロードを使用する場合は、各定義のパラメータリストは互いに区別できる必要があります。
- レストパラメータを使用する場合は、必須パラメータよりも前に配置する必要があります。
typescript