as unknown as ?

as soon asは「できるだけ早く」で、中学生の時、喉が擦り切れるほどむやみに連呼していた記憶がある。

おかげさまで、この意味を30歳超えても忘れていない。

だが、as unknown asは知らなかった。

そもそもunknownってなに?

unknownは型が分からないときに使用するらしい。

つまりそれってanyではと思うし、間違っていない。

その両方ともどのような値も代入することができる。

const any1: any = null;
const any2: any = undefined;
const any3: any = true;
const any4: any = 0.8;
const any5: any = "Comment allez-vous";
const any6: any = {
  x: 0,
  y: 1,
  name: "origin",
};
const unknown1: unknown = null;
const unknown2: unknown = undefined;
const unknown3: unknown = true;
const unknown4: unknown = 0.8;
const unknown5: unknown = "Comment allez-vous";
const unknown6: unknown = {
  x: 0,
  y: 1,
  name: "origin",
};

サバイバルTypeScriptからの引用。

違いは型チェックをするしないかという点らしい。

つまりanyを使用するとはコンパイル時には気が付けないのに対し、unknown型は一貫してTypeScriptがプロパティ、メソッドへのアクセスを行わせない。結果的にコンパイルを実行することができず、意図しないランタイム時のエラーを防止することができる。

例えば、下記コードでは'unknownValue' is of type 'unknown'.というエラーが出る。

let unknownValue: unknown = {
  x: 0,
};
unknownValue.x = "hello";

anyよりも厳格な型らしいので、unknownを使ったほうが良いのだろうか。

unknownは理解した、ではas unknown asはなに

ちなみにこの構文(as ○○ as)のことを型アサーションっていうらしい。

TypeScriptには、型推論を上書きする機能があります。その機能を型アサーション(type assertion)と言います。

TypeScriptコンパイラーはコードをヒントに型を推論してくれます。その型推論は非常に知的ですが、場合によってはコンパイラーよりもプログラマーがより正確な型を知っている場合があります。そのような場合は、型アサーションを用いるとコンパイラーに型を伝えることができます。型アサーションはコンパイラに「私を信じて!私のほうが型に詳しいから」と伝えるようなものです。

ただ、型アサーションを使用してもコンパイルエラーが出るときがある。

例えば、

const num = 123;
const str: string = num as string;

これは

Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.(2352)

というエラーが出る。

これはnumber型をstring型にするのは間違いです。お互いの型に共通する部分が少なすぎるからですというエラーらしい。

TypeScriptは無茶な上書きはできないように設計されているのだが、それでも自分の書いた型アサーションが正しいという場合は

const num = 123;
const str: string = num as unknown as string;

このように一度unknown型を経由することエラーを出さずに型推論を上書きすることができる。

サバイバルTypeScriptの警告

最後に参考にしたサバイバルTypeScriptに教訓が載っていたのでそのまま載せておく。

大いなる力には大いなる責任が伴う

型アサーションには、コンパイラーの型推論を上書きする強力さがあります。そのため、プログラマーは型アサーションによってバグを産まないように十分注意する必要があります。型に関することはできるだけ、コンパイラーの型推論に頼ったほうが安全なので、型アサーションは、やむを得ない場合にのみ使うべきです。

型アサーションを使う必要が出てきたら、それよりも先に、型ガードやユーザー定義型ガードで解決できないか検討してみるとよいでしょう。