【TypeScript】Literal 型の Widening / NonWidening を理解する

Literal型の Widening / Nonwidening TypeScript

Literal 型でアノテーションやアサーションをすると、NonWidening な Literal 型になる

let str: 'Hello' = 'Hello';
let str2 = str;
str2 = 'Goodbye'; // error: Type '"Goodbye"' is not assignable to type '"Hello"'.
let str = 'Hello' as 'Hello';
let str2 = str;
str2 = 'Goodbye'; // error: Type '"Goodbye"' is not assignable to type '"Hello"'.

このように変数に対して Literal 型でアノテーション(型注釈)やアサーションを行うと、その変数を代入した別の変数も同じ Literal 型として型推論される。このような性質を NonWidening と呼ぶ。

const 宣言による Literal 型は Widening な Literal 型になる

const str = 'Hello';  // Literal 型 'Hello' として型推論される
let str2 = str;
str2 = 'Goodbye';
console.log(str2);  // Goodbye

このように const で宣言された変数は、Literal 型 ‘Hello’ として型推論されるが、その変数を代入した別の変数は Literal 型ではなく、string 型として型推論される。そのため、’Hello’ 以外の文字列を代入できる。この性質は Widening と呼ばれる。

as const アサーションにより NonWidening かつ readonly にできる

「as const」アサーションを使用すれば、型推論の Widening を抑制することができる。

let str = 'Hello' as const; // Literal 型の "Hello" として型推論される。
let arr = [1, 2, 3] as const; // readonly [1, 2, 3] として型推論される。
let obj = {
  name: 'Tom',
  age: 33
} as const;
// {
//   readonly name: "Tom";
//   readonly age: 33;
// }
// のように型推論される。
タイトルとURLをコピーしました