質問の背景:JavaScriptでは、関数のシグネチャ内でオブジェクトのデストラクチャリングがよく使用されます。TypeScriptでは、このアプローチはデストラクチャリングするパラメータの構造を明確に定義し、デフォルト値を設定する必要があります。そうしないと、存在しないプロパティへのアクセス時にエラーが発生したり、型推論が不正確になる可能性があります。
問題:デストラクチャリングするオブジェクトの全体のパラメータや個々の入れ子のプロパティの型を正しく記述する方法が明確でないことがあります。特にオプショナルや入れ子のフィールドがある場合、デフォルト値がある場合の記述が難しくなります。
解決策:関数のパラメータの構造に対して常に個別の型またはインターフェースを記述し、どのフィールドが必須でどれがオプショナルかを明示的に示し、デフォルト値は関数本体またはパラメータ内でES6構文を使用して設定してください。
コード例:
interface UserOptions { name: string; age?: number; address?: { city: string; zipcode?: string }; } function registerUser( { name, age = 18, address = { city: 'Unknown' } }: UserOptions ): string { return `${name}, ${age}, ${address.city}`; }
主な特長:
オブジェクトパラメータの型の説明を省略し、自動推論に頼ることは可能ですか?
いいえ、これは危険です。UserOptionsの型を指定しないと、コンパイラは必須プロパティを提示せず、入れ子のフィールドのデフォルト値は適用されず、使用時に暗黙のエラーが発生します。
function example({ x, y }) { ... } // xとyはany
入れ子のオブジェクトのデフォルト値を設定し、一部のプロパティを置き換えるにはどうすればよいですか?
スプレッドを使用します。ただし、addressの型がオプショナルな場合、スプレッドは型を「結合」しません。チェックを行うか、デフォルトを明示的に設定する必要があります。
function fn({ obj = { foo: 1 } }: { obj?: { foo: number } }) { const address = { foo: 42, ...obj }; }
デフォルトなしでオプショナルフィールドをデストラクチャリングすると何が危険ですか?
オプショナルプロパティのデフォルトを省略すると、プロパティへのアクセス(たとえば、address.city)が実行時エラーを引き起こす可能性があります。明示的に?とデフォルトを設定する方が良いです。
function danger({ address }: { address?: { city: string } }) { console.log(address.city); // エラー、addressがundefinedかもしれない }
古いコードでは、明示的な型指定なしにパラメータオブジェクトをデストラクチャリングしていました。関数に新しいフィールドを追加すると、すべての使用場所が自動的に見つからず、プロダクションでの呼び出しが壊れました。
利点:
欠点:
すべての関数にインターフェースを導入し、undefinedおよびデフォルト値に関するシナリオをテストカバーし、コンパイラのヒントにより大規模な変更を容易に行えるようにしました。
利点:
欠点: