TypeScriptの型についていくつか試してみます。
string / number / boolean
stringは文字列の型です。
let text: string = 'テキスト'; console.log(text); // テキスト
文字列以外を代入しようとすると、コンパイルエラーになります。
let text: string = 'テキスト'; console.log(text); // テキスト text = 100; // error TS2322: Type 'number' is not assignable to type 'string'.
numberは数値の型です。
小数や負の値もnumberに含まれます。
let number: number = 100; console.log(number); // 100 number = 1.5; console.log(number); // 1.5 number = -10; console.log(number); // -10 number = '100'; // error TS2322: Type 'string' is not assignable to type 'number'.
booleanは真偽値の型です。
let flag: boolean = true; console.log(flag); // true flag = 'false'; // error TS2322: Type 'string' is not assignable to type 'boolean'.
配列
次に配列の型の指定です。
例として数値の値を持つ配列の場合、型の指定はnumber[] のようになります。
const score: number[] = [72, 78, 67, 86, 83]; console.log(score); // [72, 78, 67, 86, 83]
数値以外を追加しようとすると、コンパイルエラーになります。
const score: number[] = [72, 78, 67, 86, 83]; console.log(score); // [72, 78, 67, 86, 83] score.push('80'); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
数値と文字列が混在する配列の場合、後述するユニオン型を使うことで複数の型の指定もできます。
const score: (string | number)[] = [72, 78, 67, 86, '83']; console.log(score);
any
anyはどんな型でも代入できる型で、TypeScriptでの型チェック無効にします。
let value: any = 'テキスト'; console.log(value); // テキスト value = 100; console.log(value); // 100 value = [72, 78, 67, 86, 83]; console.log(value); // [72, 78, 67, 86, 83]
TypeScriptの型安全性が失われるため、基本的には使用しないか最小限の使用に留めておく方がよさそうです。
変数の型注釈について
今までの例でも使用していますが、変数を宣言する際に型注釈を追加することで、変数の型を明示的に指定できます。
let text: string = 'テキスト';
ただ実際には、TypeScript側でコード内の型を自動的に推論してくれる(型推論)ので、基本的には型注釈を追加しなくても問題ありません。
let text = 'テキスト'; console.log(text); // テキスト text = 100; // error TS2322: Type 'number' is not assignable to type 'string'.
関数
関数は各引数の後に型注釈を追加することで、型を指定できます。
function greet(name: string) { console.log(`Hello, ${name}`); } greet('Suzuki'); // Hello, Suzuki greet(100); // error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
返り値の型の指定は、引数の括弧の後に指定します。
function add(num1: number, num2: number): number { return num1 + num2; } console.log(add(1, 2)); // 3
異なる型を返そうとすると、コンパイルエラーになります。
function add(num1: number, num2: number): number { if(num1 + num2 <= 10) return num1 + num2; return false; // error TS2322: Type 'boolean' is not assignable to type 'number'. }
返り値の型注釈については変数と同じで、省略してもreturnの内容から推論してくれるので、基本的には型注釈を追加しなくても問題ありません。
function add(num1: number, num2: number) { if(num1 + num2 <= 10) return num1 + num2; return false; }
オブジェクト
オブジェクトの型の指定は以下のようになります。
const item: { name: string; price: number; } = { name: 'apple', price: 200 } console.log(item.name); // apple
異なる型を代入しようとするとコンパイルエラーになります。
const item: { name: string; price: number; } = { name: 'apple', price: 200 } console.log(item.name); // apple item.price = '150'; // error TS2322: Type 'string' is not assignable to type 'number'.
ユニオン型
ユニオン型は複数の型を指定して、そのうちのいずれかの型になります。
let val: string | number = 'テキスト'; console.log(val); // テキスト val = 100; console.log(val); // 100 val = true; // error TS2322: Type 'boolean' is not assignable to type 'string | number'.
ユニオン型を使用した際、代入した値の型で使用できないプロパティやメソッドの場合はコンパイルエラーになります。
let val: string | number = 'テキスト'; console.log(val.length); // 3 val = 100; console.log(val.length); // error TS2339: Property 'length' does not exist on type 'number'.
以下のような関数の場合、引数の型がstringの場合は問題ないですが、numberの場合はlengthのプロパティが存在しないためコンパイルエラーになります。
function textLEngth(val: string | number) { return val.length; // Property 'length' does not exist on type 'string | number'. Property 'length' does not exist on type 'number'. }
typeofなどを使って、型に応じて処理を分けることで解消できます。
function textLEngth(val: string | number) { if (typeof val === "string") { return val.length; } else { return String(val).length; } } console.log(textLEngth('テキスト')); // 4 console.log(textLEngth(100)); // 3
型エイリアス
型エイリアス(type alias)は名前を付けた型のことで、同じ型を複数回使用したい時などに便利です。
typeキーワードを使って指定します。
type BtnSize = 'sm' | 'md' | 'lg' | 'xl'; let btnSize: BtnSize = 'sm'; btnSize = 'xxl'; // error TS2322: Type '"xxl"' is not assignable to type 'BtnSize'.
インターフェース
インターフェースは、オブジェクトの型に名前を付ける方法です。
interfaceキーワードを使って指定します。
interface Item { name: string; price: number; } const item: Item = { name: 'apple', price: 200 } console.log(item.name) // apple
型アサーション
型アサーション(type assertion)は、値の型が不明瞭な場合に明示的に指定できる機能です。
例えば以下のようにgetElementById()を使用すると、型はHTMLElement(取得できた場合)かnull(取得できなかった場合)になります。
そのため、valueプロパティを使おうとするとコンパイルエラーになります。
const input = document.getElementById("input-text"); input.value = "こんにちは"; // error TS18047: 'input' is possibly 'null'. // error TS2339: Property 'value' does not exist on type 'HTMLElement'.
型アサーションを使って型がHTMLInputElementと明示的に指定することで、valueプロパティを使ってもコンパイルエラーにならなくなります。
const input = document.getElementById("input-text") as HTMLInputElement; input.value = "こんにちは";
リテラル型
リテラル型(literal type)は、特定の文字列または数値の値だけを使用できるようにする型です。
let greet: 'Hello' = 'Hello'; greet = 'Hi'; // error TS2322: Type '"Hi"' is not assignable to type '"Hello"'.
前述のユニオン型と合わせて使うことで、特定の値からのみ代入できるといった指定が可能です。
let btnStyle: 'sm' | 'md' | 'lg' | 'xl' = 'sm'; btnStyle = 'md'; btnStyle = 'xxl'; // Type '"xxl"' is not assignable to type '"sm" | "md" | "lg" | "xl"'.
null / undefined
nullとundefinedは名前の通り、nullとundefinedのみ許容する型です。
let testA: null = null; console.log(testA); // null testA = 'テスト'; // error TS2322: Type '"テスト"' is not assignable to type 'null'. let testB: undefined = undefined; console.log(testB); // undefined testB = 'テスト'; // error TS2322: Type '"テスト"' is not assignable to type 'undefined'.
列挙型
列挙型(Enum)は、定数のグループに名前を付ける機能です。
enumキーワードを使って指定します。
enum BtnSize { Sm = 'sm', Md = 'md', Lg = 'lg', Xl = 'xl' } const btnStyle = { label: 'ボタン', size: BtnSize.Sm } console.log(btnStyle); // {label: 'ボタン', size: 'sm'} btnStyle.size = BtnSize.Lg; console.log(btnStyle); // {label: 'ボタン', size: 'lg'} // btnStyle.size = 'sm'; // error TS2322: Type '"sm"' is not assignable to type 'BtnSize'.
コメントが承認されるまで時間がかかります。