キャストについて混乱していますas const
。いくつかのドキュメントとビデオを確認しましたが、完全には理解できませんでした。
私の懸念は、as const
以下のコードの意味と、それを使用することによる利点は何ですか?
const args = [8, 5] as const;
const angle = Math.atan2(...args);
console.log(angle);
ベストアンサー1
これは、const
主張アサーションは、式に対して可能な限り狭い*または最も具体的なconst
型を推論するようにコンパイラに指示します。アサーションを省略すると、コンパイラはデフォルトの型推論動作を使用し、より広い型またはより一般的な型になる可能性があります。
これは「アサーション」と呼ばれ、「キャスト」ではないことに注意してください。「キャスト」という用語は、TypeScriptでは一般的に避けられます。「キャスト」と言うと、実行時に観察できる何らかの効果を意味することがよくありますが、TypeScriptの型システム(型アサーションやconst
アサーションを含む)は完全に消去された出力された JavaScript から。したがって、使用するプログラムと使用しないプログラムの間には実行時にまったく違いはありません。as const
as const
しかし、コンパイル時には、顕著な違いがあります。上記の例で省略すると何が起こるか見てみましょう。
const args = [8, 5];
// const args: number[]
const angle = Math.atan2(...args); // error! Expected 2 arguments, but got 0 or more.
console.log(angle);
コンパイラはconst args = [8, 5];
の型を見て推論しますnumber[]
。これは、 型の 0 個以上の要素を持つ可変配列です。コンパイラは、要素がいくつあるか、またはどのnumber
要素があるかは知りません。このような推論は一般に妥当です。多くの場合、配列の内容は何らかの方法で変更されることが意図されています。または を書きたい場合、 の型で十分です。args.push(17)
args[0]++
number[]
残念ながら、次の行Math.atan2(...args)
ではエラーが発生します。Math.atan2()
関数には、正確に 2 つの数値引数が必要です。しかし、コンパイラが認識しているのは、それが数値の配列であることだけです。要素が 2 つあることを完全に忘れているため、コンパイラは、正確に 2 つの引数が必要なのに、「0 個以上」の引数でargs
呼び出しているとエラーを出力します。Math.atan2()
これを次のコードと比較してくださいas const
:
const args = [8, 5] as const;
// const args: readonly [8, 5]
const angle = Math.atan2(...args); // okay
console.log(angle);
コンパイラは、...aargs
型であると推論します。readonly [8, 5]
readonly
タプルその値はまさにその数字であり8
、5
その順序になっています。具体的には、コンパイラによってargs.length
正確であることがわかっています。2
そして、これは の次の行が機能するのに十分ですMath.atan2()
。コンパイラーは がMath.atan2(...args)
と同じでありMath.atan2(8, 5)
、有効な呼び出しであることを認識します。
繰り返しますが、実行時にはまったく違いはありません。どちらのバージョンも1.0121970114513341
コンソールにログを記録します。ただし、const
アサーションは、静的型システムの他の部分と同様に、実行時に効果を発揮するものではありません。代わりに、アサーションによってコンパイラーはコードの意図をより詳しく知ることができ、正しいコードとバグの違いをより正確に判別できるようになります。
* これは配列型とタプル型には厳密には当てはまりません。readonly
配列またはタプルは技術的には可変バージョンよりも範囲が広くなります。可変配列は配列のサブタイプと見なされます。前者には後者のreadonly
ような変更メソッドがあることは知られていません。push()