TypeScriptにおいて、any、unknown、およびobject型は異なるシナリオで使用され、重要な違いがあります:
any:変数の型システムを無効にします。コンパイルエラーを引き起こさずに、変数に対して何でも実行できます。オブジェクトの型が事前に不明で、安全性が重要でない場合に使用します。unknown:任意の型を受け入れますが、そのような変数を操作するには明示的な型チェック/キャストが必要です。anyよりも安全です。型が不明な値に使用して、型管理を失わないようにします。object:プリミティブ(数値、文字列)ではなく、非原始的なオブジェクト(オブジェクト、配列、関数)のみの型です。オブジェクトでの操作のみを制限します。let a: any = 1; a = 'string'; // OK a(); // OK(しかし、ランタイムエラーの原因となる可能性があります) let b: unknown = 'hello'; b = 5; // OK // b.toUpperCase(); // エラー—型チェックが必要 if (typeof b === 'string') { console.log(b.toUpperCase()); } let c: object = { key: 'value' }; c = [1, 2, 3]; // OK // c = 1; // エラー、'1'はオブジェクトではないため
質問:なぜanyを使用できるのに、unknownが役に立つのですか?
答え:unknownはコードの安全性を高めます—anyのように未確認の操作を行うことはできません。型を明示的に確認またはキャストする必要があるため、実行時に多くの驚きを排除します。
function handle(value: unknown) { // value.trim(); // エラー if (typeof value === 'string') { value.trim(); } }
物語
プロジェクトで外部ライブラリを迅速に統合し、型を気にせずにanyでその結果を記述することにしました。結果として、ライブラリが配列ではなくフィールドを持つオブジェクトを返すことに気づき、.map()メソッドに多数のエラーが発生しました—このコードはコンパイルされましたが、実行時に失敗しました。
物語
開発者の一人は、バックエンドから来たデータにunknownを使用しましたが、フィールド操作の前に型チェックを追加しませんでした。その結果、TypeScriptはコードをコンパイルせず、急いでanyに変更する必要があり、パースエラーの潜在的な問題が隠され、データの不正な形式により本番環境でバグが発生しました。
物語
object型を使用する際に混乱が生じました:object型の変数にstringやnumberの値を代入しようとしました。開発段階では問題に気づきませんでしたが、レビュー中に、オブジェクトのメソッドがプリミティブでは動作しないというエラーが発生しました。修正には追加の時間がかかりました。