2019/09/10

TypeScriptの似ているようで違うvoid/never型とany/unknown型の比較

TypeScriptは業務で使っているが、脳内バージョンは2.x系で最新情報を追ってこなかった。その弊害として、never型とunknown型の意味がわからず、void/anyと何が違うの?状態だった。

そこで当記事ではvoidとnever、anyとunknownのそれぞれの型の特徴を一言、二言で表し比較する。

void型とnever型

void型

void型は値がないことを指している。ただし、void型にはundefinedが含まれる。
JavaScriptの関数でreturnを省略、または戻り値のないreturnをするとundefinedが返される。
const hello = (name: string): void => {
  console.log('hello', name)
  return undefined  // or return
}

▶ Basic Types#void · TypeScript


never型

never型は発生し得ない値のことを指している。関数内部で例外を投げる場合や無限ループをする場合など、戻り値が得られないときにしか使えない。
void型と違いundefinedも受け付けないため、戻り値の型にneverを指定した場合はreturnすることはできない。
// () => never
const panic = (msg: string): never => {
  throw new Error(msg)
}

// ↓はコンパイルエラーになる
const hello = (name: string): never => {
  console.log('hello', name)
  // returnが省略されている場合はundefinedを返すためnever型にならない
}

▶ Basic Types#never · TypeScript



any型とunknown型

any型

なんでもござれの超懐の広い型(型を無視する
val as any as MyTypeのように使うとどんな型でも変換できる。
const list: any[] = [1, '2']

// ランタイムエラーになる('2'がstringなのでtoFixedできない)
list.forEach(a => console.log(a.toFixed(1))

▶ Basic Types#any · TypeScript


unknown型

TypeScript3.0から導入された型。値を代入するときはany型と同じく寛容だが、値を利用するときに厳しく型をチェックされる。
const list: unknown[] = [1, '2']

// コンパイルエラーになる
list.forEach(a => console.log(a.toFixed(1))

// エラーにならない
list.forEach(a => {
  // Type guard
  if (isString(a)) {
    return console.log(a.toUpperCase())
  }
  if (isNumber(a)) {
    return console.log(a.toFixed(1))
  }
})

const isString = (val: unknown): val is string => {
  return typeof val === 'string'
}
const isNumber = (val: unknown): val is number => {
  return typeof val === 'number'
}

▶ TypeScript 3.0#unknown · TypeScript



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿