web-dev-qa-db-ja.com

「不明」と「任意」

TypeScript 3.0では、そのウィキによるとunknown型が導入されています。

unknownは組み込みの型になったため、現在はunknownが予約型の名前になっています。あなたが意図したunknownの使用法に応じて、宣言を完全に削除する(新しく導入されたunknown型を優先する)か、あるいはそれを別の名前に変更したいと思うかもしれません。

unknownanyの違いは何ですか? unknownよりanyをいつ使用すべきですか。

70
Jacoslaw

unknownについての詳細は PR または RC発表 で読むことができますが、その要旨は以下のとおりです。

[..] unknownは、anyの型安全な対応物です。未知のものには何でも代入できますが、未知のものには代入できないし、型のアサーションや制御フローに基づく絞り込みがないと何にも代入できません。同様に、最初により具体的なタイプを表明または絞り込むことなしに、未知のものに対して操作を行うことはできません。

いくつかの例:

let vAny: any = 10;          // We can assign anthing to any
let vUnknown: unknown =  10; // We can assign anthing to unknown just like any 


let s1: string = vAny;     // Any is assigable to anything 
let s2: string = vUnknown; // Invalid we can't assign vUnknown to any other type (without an explicit assertion)

vAny.method();     // ok anything goes with any
vUnknown.method(); // not ok, we don't know anything about this variable

推奨される使い方は次のとおりです。

TypeScriptで最も能力の低い型を記述したいことがよくあります。これは、「これは任意の値になる可能性があるため、使用する前に何らかの種類のチェックを実行する必要があります」というシグナルを送りたいAPIに役立ちます。これにより、ユーザーは戻り値を安全にイントロスペクトする必要があります。

Unknownとanyの違いは、次のとおりです。

anyと同様に、任意の値をunknownに代入できます。ただし、anyとは異なり、unknown型の値のプロパティにアクセスすることはできません。また、それらを呼び出したり構築することもできません。さらに、unknown型の値は、unknownまたはanyにのみ割り当てることができます。

unknownの上でanyを使うべきなのかというあなたの質問に答えるには、

これは、「これは任意の値にすることができるので、使用する前にmustのいずれかの種類のチェックを実行する必要があります」というシグナルを送りたいAPIに役立ちます。これにより、ユーザーは戻り値を安全にイントロスペクトする必要があります。

unknownの変数を型チェックする例と、より詳細な説明については、 TypeScript 3.0の発表 をご覧ください。

14
Awad Maharoof

anyタイプ:

anyタイプは、可能なすべてのJS値を表します。すべての型は、any型に割り当て可能です。したがって、タイプanyは、タイプシステムのユニバーサルスーパータイプです。 TSコンパイラは、anyと入力された値に対する操作を許可します。例えば:

let myVar: any;

myVar[0];
myVar();
myVar.length;
new myVar();

多くの場合、これはTSコンパイラにはあまりにも寛大です。つまり、実行時エラーが発生することがわかっていた操作を許可します。

unknownタイプ:

unknown型は、(anyと同様に)すべての可能なJS値を表します。すべての型は、unknown型に割り当て可能です。したがって、タイプunknownは、(anyと並んで)タイプシステムの別のユニバーサルスーパータイプです。ただし、TSコンパイラーwo n'tは、unknownと入力された値に対する操作を許可します。さらに、unknown型は、any型にのみ割り当て可能です。例はこれを明確にします:

let myVar: unknown;

let myVar1: unknown = myVar;   // No error
let myVar2: any = myVar;       // No error
let myVar3: boolean = myVar;   // Type 'unknown' is not assignable to type 'boolean'

// The following operations on myVar all give the error:
// Object is of type 'unknown'
myVar[0];
myVar();
myVar.length;
new myVar();
3