LoginSignup
23
9

More than 5 years have passed since last update.

TypeScript - WideningLiteralTypes -

Last updated at Posted at 2018-10-05

LiteralTypes の Widening / NonWidening -

let / const で明示的型キャストを付与せずに宣言すると以下のとおりとなる。

const ONE = 1 // ONE: 1
let TWO = 2   // TWO: number

const によるプリミティブの暗黙的型キャストは LiteralTypes となるが、これが普通の LiteralTypes ではない。以下では Numeric で解説するが、LiteralTypes において当てはまる。Annotation / Assertion を付与すると NonWidening となり、明示的型キャストがない場合 Widening となる。これは VSCode などの見た目上では気づかない。

const THREE = 3 //    THREE: 3 (Widening NumericLiteralTypes)
const FOUR: 4 = 4 //   FOUR: 4 (NonWidening NumericLiteralTypes)
const FIVE = 5 as 5 // FIVE: 5 (NonWidening NumericLiteralTypes)

WideningLiteralType について

TypeScript2.1にひっそりと書かれていることと、よく参照されるissueにまとまっている。LiteralTypes と双方互換がある別型と認識した方が良さそう。

const c1 = cond ? "foo" : "bar";  // widening "foo" | widening "bar"
const c2: "foo" | "bar" = c1;  // "foo" | "bar"
const c3 = cond ? c1 : c2;  // "foo" | "bar"
const c4 = cond ? c3 : "baz";  // "foo" | "bar" | widening "baz"
const c5: "foo" | "bar" | "baz" = c4; // "foo" | "bar" | "baz"
let v1 = c1;  // string
let v2 = c2;  // "foo" | "bar"
let v3 = c3;  // "foo" | "bar"
let v4 = c4;  // string
let v5 = c5;  // "foo" | "bar" | "baz"

挙動の違い

冒頭の通り、推論結果の見た目上では Widening / NonWidening は判別できない。

const INCREMENT = "INCREMENT"
const SET_COUNT = "SET_COUNT" as "SET_COUNT"
/** 【推論結果】 **/
const INCREMENT: "INCREMENT"
const SET_COUNT: "SET_COUNT"

WideningStringLiteral は object に代入することで、string型になる。

const object = {
  INCREMENT, // (Widening)
  SET_COUNT, // (NonWidening)
}
/** 【推論結果】 **/
const object: {
  INCREMENT: string;
  SET_COUNT: "SET_COUNT";
}

WideningLiteral instance に対し、typeof WideningLiteral instance で Assertion を付与すると、NonWideningLiteral になる。

const object = {
  INCREMENT: INCREMENT as (typeof INCREMENT),
  SET_COUNT
}

/** 【推論結果】 **/
const object: {
  INCREMENT: "INCREMENT";
  SET_COUNT: "SET_COUNT";
}

const は再代入不可であり、object は再代入可能という性質の折衷案と察した。widening に気づきやすい環境に期待。

23
9
1

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
23
9