はじめに
業務などでTypeScriptを触っていく中で、たびたび見るany型、unknown型、never型。
これらに対して毎回「あれ、違いなんだっけ?」となってしまうので、、サバイバルTypeScriptを基にこの記事で整理しようと思います!
any型
まずany
型を見ていきます。
サバイバルTypeScriptによると以下のようです。
TypeScriptのany型は、どんな型でも代入を許す型です。プリミティブ型であれオブジェクトであれ何を代入してもエラーになりません。
any
型は TypeScriptの型チェックを無効化します。
なのでboolean型だろうが、number型だろうが、どんな型の値でも格納できてしまいます。
let anyType: any = "stringです"
anyType = true // boolean型も代入できてしまう
anyType = 1111 // number型も代入できてしまう
また、any
型の変数は どんな型の変数にも代入可能 です。
const anyType: any = "any型です";
const num: number = anyType; // エラーなし
const bool: boolean = anyType; // エラーなし
このようにany
型を使うと型チェックが完全に無効化されるため、型の安全性が失われてしまいます。
あくまで最終手段として使うのが良さそうです。
unknown型
続いてunknown
型を見ていきます。
unknown
型は以下のようです。
TypeScriptのunknown型は、型が何かわからないときに使う型です。
unknown型にはどのような値も代入できます。
どんな型でも格納できるという点ではany
型と同じです。
let unknownType: unknown = "stringです"
unknownType = true // boolean型も代入できてしまう
unknownType = 1111 // number型も代入できてしまう
しかし、unknown
型の値を他の型の変数に代入しようとするとエラーになるという制約があります。
その点でany
型とは異なります。
const unknownType: unknown = "unknown型です";
//↓エラー発生:Type 'unknown' is not assignable to type 'number'.
const int: number = unknownType;
//↓エラー発生:Type 'unknown' is not assignable to type 'boolean'.
const bool: boolean = unknownType;
他の型に代入したい場合は以下のように型ガードをつかいます。
const unknownType: unknown = "unknownです。"
if (typeof unknownType === "string") {
// ここでは、string型として扱える
// エラーは発生しない
const str: string = unknownType
}
any型みたいに柔軟に型を使いたいが、型安全性は保ちたい、、、。そんな時にunknown型が使えそうです。
never型
最後にnever
型を見ていきます。
never
型は以下になります。
never型は「値を持たない」を意味するTypeScriptの特別な型です。
参考:サバイバルTypeScript-never型
any
型とunknown
型ではどんな型でも格納できますが、never
型に関しては値を一切持てません。
格納できるのはnever
型のみになります。
//↓エラーが発生:Type '"neverです"' is not assignable to type 'never'.
const neverType: never = "never型です";
//これはOK
const neverType: never = "neverです" as never
ですが、どんな型に対しても代入はできるみたいです。
const neverType: never = "neverです" as never
const stringType: string = neverType //エラーなし
const intType: number = neverType //エラーなし
never
型は、主に以下のように値も返さない状態を表すために使われます。
例1: 例外を投げる場合
function throwError(message: string): never {
throw new Error(message);
}
参考:サバイバルTypeScript-never型
例2: 無限ループする場合
function forever(): never {
while (true) {} // 無限ループ
}
まとめ
any
型unknown
型never
型の違いを整理すると、以下のようになります。
型 | 特徴 | 代入時の挙動 |
---|---|---|
any |
どんな型でも格納可能 | どの型にも代入可能 |
unknown |
どんな型でも格納可能 | 型ガードすればどの型にも代入可能 |
never |
値を持たない | どんな型にも代入できるが、値は持てない |
使い道
any
型は型チェックを無視するため、基本的には使用を避けるほうが好ましい。
unknown
型は安全性を保ちつつ柔軟に使えるため、どの型を持つか不明な場合に有効。
never
型は例外が発生する関数の戻り値などで使用。
記事に書いたことで違いが整理されたような気がします。
僕と同じように「結局、この3つの違いって何だっけ?」と悩む方のお役に立てれば嬉しいです。