こんにちは! 株式会社アルシエで教育に関するサポートをしている岸本です。
今回のテーマは「TypeScriptパート2」です!
Literal Types
Literal Typesとは、プリミティブ型で特定の値だけを代入可能にする型を表現できます。
以下のコードのように、booleanではなくtrueとする事でtrue以外の値を代入できなくなります。
Literal Typesは、値を限定させる事で補完やタイポを防ぐ事ができます。
// boolean literal types: isTrueにtrue以外の値を入れるとエラー
const isTrue: true = true;
// string literal types : fooに"foo"以外の値を入れるとエラー
const foo: "foo" = "foo";
// number literal types : numTwoに2以外の値を入れるとエラー
const numTwo: 2 = 2;
Widening
Wideningとは、もともとLiteral Typesだとしても、再代入が可能な変数やオブジェクトのプロパティなどに代入するとLiteral Typesからstring、numberなどに拡張されてしまう事です。
const bar = "bar" // bar: "bar"
let foo = bar // foo: string
コードを書いていく中で、再代入が可能なものに入れたとしてLiteral Typesのままにしたい場合は以下のように記述します。
// 型アノテーション
const bar: "bar" = "bar"
let foo = bar // foo: "bar"
// 型アサーション
const bar = "bar" as "bar"
let foo = bar // foo: "bar"
// const アサーション
const bar = "bar" as const
let foo = bar // foo: "bar"
constとletの型推論には違いがあります。letの場合、後から再代入できるのでWideningになります。
const bar = "bar" // bar: "bar"
let bar = "bar" // bar: string
「Widening」とは、型が拡張されてしまうことを意味し、これはLiteral Typesに限定されるものではありません。
色々な型
Array(配列)
// 同じ挙動 bar: number[]
const bar: number[] = [1,2,3,4,5]
const bar: Array<number> = [1,2,3,4,5]
Tuple
Tupleは一つ一つの要素に型をつける事ができます。
以下のコードでは、1つ目の要素はstring型で2つ目の要素はnumber
型と指定する事ができます。
const bar: [string,number] = ["DLA",3]
3つ目の要素を増やしたり、型が違う値を入れるとエラーが出ます。
// string を型 number に割り当てることはできません
const bar: [string,number] = ["DLA","3"]
Tupleであれば、その要素のメソッドの補完が出ます。
const bar: [string,number] = ["DLA",3]
// toFixedなどnumberのメソッド補完が出ます
bar[1].toFixed(4)
Any
any型は、型チェックをしない型です。
any型は多用しない方がいいです!
any型を使うことで、型チェックを回避することができますが、型の安全性が失われてコードのバグを生みやすくなるというデメリットがあります。
// なんでも代入が可能
const bar: any = {};
const bar: any = 3;
const bar: any = true;
Unknown
anyと同様に、型が不明な場合に使用し、なるべく型安全にしたい場合に使用します。
anyと同様に多用しない方がいいです!
// なんでも代入可能
const bar: unknown = true;
const bar: unknown = "あいうえお";
const bar: unknown = 4;
Unknownを利用すると、型安全性が向上します。
// anyの場合
const bar: any = "any";
// toFixed()はnumber型のメソッドなのでエラー
bar.toFixed(4); // anyはエラーがでない
// unknownの場合
const bar: unknown = "any";
bar.toFixed(4); // bar''は unknown 型です
const bar: unknown = "any";
// anyはstring型なのでエラーがでているが、実行する事はできる
// しかし、エラーが出ているのでコンパイルができない
bar.toUpperCase(); // string型のメソッドを使ってもエラー
// そんなときにエラーを無くしコンパイルする方法
// if文でbarがstring型と絞り込むとコンパイル可能!
const bar: unknown = "any";
if (typeof bar === "string") {
bar.toUpperCase();
}
Void
関数の返り値がない場合によく使います。
const bar = ():void => {
console.log("あいうえお");
};
// :void型に返り値があるとエラーが出ます
const bar = ():void => {
console.log("あいうえお");
return 3 // number を型 void に割り当てることはできません
};
以下のコードは、返り値の型の書き方が異なるだけです。
const bar : () => void = () => {
console.log("あいうえお");
};
const bar = ():void => {
console.log("あいうえお");
};
Never
never型は「値を持たない」を意味します。
たとえば、例外が必ず発生する関数の戻り値です。戻り値は絶対に取れません。そのため、戻り値の型はnever型になります。
function throwError(): never {
throw new Error();
}
以上となります!
次回はTypeScriptパート3です!