6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TypeScript】意外と曖昧になりがち、、、any型、unknown型、never型の違いについて整理

Posted at

はじめに

業務などでTypeScriptを触っていく中で、たびたび見るany型、unknown型、never型。
これらに対して毎回「あれ、違いなんだっけ?」となってしまうので、、サバイバルTypeScriptを基にこの記事で整理しようと思います!

any型

まずany型を見ていきます。
サバイバルTypeScriptによると以下のようです。

TypeScriptのany型は、どんな型でも代入を許す型です。プリミティブ型であれオブジェクトであれ何を代入してもエラーになりません。

参考:サバイバル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型にはどのような値も代入できます。

参考:サバイバルTypeScript-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) {} // 無限ループ
}

参考:サバイバルTypeScript-never型

まとめ

anyunknownnever型の違いを整理すると、以下のようになります。

特徴 代入時の挙動
any どんな型でも格納可能 どの型にも代入可能
unknown どんな型でも格納可能 型ガードすればどの型にも代入可能
never   値を持たない どんな型にも代入できるが、値は持てない

使い道

any型は型チェックを無視するため、基本的には使用を避けるほうが好ましい。
unknown型は安全性を保ちつつ柔軟に使えるため、どの型を持つか不明な場合に有効。
never型は例外が発生する関数の戻り値などで使用。

記事に書いたことで違いが整理されたような気がします。
僕と同じように「結局、この3つの違いって何だっけ?」と悩む方のお役に立てれば嬉しいです。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?