Typescript(リテラル型)
はじめに
今回は、プリミティブ型をさらに厳密に指定したリテラル型について記事を書きます。リテラル型には大きく3種類あり、stringのリテラル型、numberのリテラル型、Boorianのリテラル型です。
リテラル型の定義
以下、stringのリテラル型です。
const foo: "foo" = "foo"; const bar: "foo" = "bar";//エラー
型指定には: "foo"stringとstringの中でも'foo'という文字列に限定しています。よってbarなどのfoo以外の文字列を代入することはできません。
もちろん型指定せず、型推論に頼ることも可能です。
const foo = "foo"; //型は"foo"
この例は、javascriptでのconstは再代入できないことを保証する宣言方法なのでリテラル型での型推論を可能にしています。つまり'foo'という文字列から他の値に変化しないことを保証するための型推論です。
察しの良い方は気づいていると思いますが、letでの宣言方法で型推論に頼ると結果が変わってきます。
let foo = "foo"; //型はstring
また、letで宣言する場合も型指定すればリテラル型を持たせることができます。
let foo: "foo" = "foo"; //型は'foo'
因みに、const foo: 'foo' = 'foo'とconst foo ='foo'はfooにホバーすると'foo'と型推論は同じですが、機能としては違いがあります。それは、letなど後で変更することを許可する方法でfooを再代入する場合に違いが生じます。
const foo: "foo" = "foo"; let foo1 = foo; //型は'foo' const foo = "foo"; let foo2 = foo; //型は'string'
オブジェクトによるリテラル型の利用
先にコードで例を見てみましょう。
const person = { firstname: "uzumaki", lastname: "naruto", }; person.firstname = "utiha"; console.log(person)//{firstname: "utiha", lastname: "naruto"}
まずpersonというオブジェクトを作りました。constで宣言していますが、firstname,lastnameともにstringと型推論されています。
これによりfirstname,lastnameともに書き換え可能となってしまうというコードです。
これを書き換え不可のコードにするには2つの改善方法があります。
①//型エイリアス type Person = { firstname: "uzumaki"; lastname: "naruto"; }; const person: Person = { firstname: "uzumaki", lastname: "naruto", }; person.firstname = "utiha";//エラー ②//constアサーション const person = { firstname: "uzumaki", lastname: "naruto", } as const; person.firstname = "utiha";//エラー
個人的には、②の方が記述量も少なく、直感的でわかりやすく感じます。また②ではリテラル型で型推論されています。
また今回はオブジェクトに注目しましたが、配列でも要素の書き換え不可のコードをas const(readoly)を使うことで可能にします。