🐷
[TypeScript] Wideningについて調べてみた
はじめに
以前TypeScriptのWideningに惑わされたので、今回はWideningの基本的な部分を記事にまとめようと思いました。
constとletの型推論の違い
const foo = 'foo' // fooは"foo"型
let bar = 'bar' // barはstring型
上記のようにconst
とlet
では型推論に違いが出ます。
理由としては、const
は再代入不可なのに対して、let
は再代入が可能だからです。
仮にlet
で宣言した変数の型がリテラル型に推論されてしまうと再代入できる意味がなくなってしまいます。
だからこそlet
の場合はリテラル型ではなくプリミティブ型に推論されます。
ちなみにこれもWideningの一つでstring型に限らずboolean型やnumber型でも同様の挙動になります。
Widening
const foo = 'foo' // fooは"foo"型
let bar = foo // barはstring型
const
で宣言した変数(リテラル型)をlet
で宣言した変数の中に代入すると、勝手に対応するプリミティブ型に拡張されてしまいます。
これがWideningと呼ばれるものになります。
Wideningしてほしくない時
以下の方法を利用してリテラル型を明示的に入れておくことで、Wideningな性質を排除することができ、
let
で宣言した変数の型のリテラル型のままになります。
型アノテーション
const foo: 'foo' = 'foo' // fooは"foo"型
let bar = foo // barは"foo"型
型アサーション
const foo = 'foo' as 'foo' // fooは"foo"型
let bar = foo // barは"foo"型
constアサーション
const foo = 'foo' as const // fooは"foo"型
let bar = foo // barは"foo"型
おわり
今回はWideningの基本的をまとめてみました。
オブジェクトのプロパティも再代入が可能なため、オブジェクトリテラルの中でも今回見たようなリテラル型のWideningが発生します。
機会があればそちらについてもまとめてみたいと思います!
参考
Discussion