こんにちは! 株式会社アルシエで教育に関するサポートをしている岸本です。
今回のテーマは「TypeScriptパート4」です。
typeof
typeofは型を取得することができます。
let foo: string;
type Bar = typeof foo; // Bar は string型
let foo: number;
type Bar = typeof foo; // Bar は number型
Literal Typesとしても取得できます。
const foo = "foo";
type Bar = typeof foo; // Bar = "foo"
オブジェクトの型定義で、同じ型を別のオブジェクトでも使用する場合に役立ちます。
const taro = {
name: "Taro",
age: 20,
};
const jiro: typeof taro = {
name: "Jiro",
age: 40,
};
// ageがありません!とエラー
const jiro: typeof taro = {
name: "Jiro",
};
型ガードでも使われます。
型ガードとはif文やcase文をはじめとした条件分岐で変数の型を判別し、型を絞り込む機能のことをいいます。
const convert = (value: string | number): string => {
// valueがstringのとき
if (typeof value === 'string') {
return value.toUpperCase(); // string型と推論される
} else {
return value.toString(); // number型と推論される
}
}
keyof
オブジェクトのプロパティ名をLiteral Typesとして取得する事ができます。
keyofは型定義に対して使います。
type taro = {
name: string,
age: number,
};
// Key は "name" | "age" のUnion Typesになっている
type Key = keyof taro
ダウンキャスト
ダウンキャストとは、一度定義した型を厳密化することです。
以下のコードでは、colorはLiteral Typesですがtheme1の中にあるcolorはstring型
になっています。
この挙動になっている理由は、TypescriptがJavascriptの使用に基づき作られているからです。
オブジェクトのプロパティだとconstで宣言しても変更が可能なのでstring型になっています。
// colorは "red"
const color = "red"
// color は string型
const theme1 = {
color: "red",
};
string型からLiteral Typesにしたい場合、型を厳密化したい時をダウンキャストといいます。
コードでは、as constを記述するだけでcolorがLiteral Typesになります。
// colorは "red"
const color = "red"
// color は "red"
const theme1 = {
color: "red" as "red",
};
もし、theme1のプロパティが増えた場合、毎回 as を書くのは大変だと思います。
そんな時は以下のコードを書くといいと思います。
const theme1 = {
color: "red"
backGroundColor: "blue",
}as const;
// theme1.colorの型はconstアサーションされているため、エラーになる
theme1.color = "blue"
// theme1.backGroundColorの型はconstアサーションされているため、エラーになる
theme1.backGroundColor = "red"
ダウンキャストは widening の防止にも役立ちます。
アップキャスト
アップキャストとは、一度定義した型を抽象化することです。
型を抽象化するためバグを生みやすなり、あまり使うべきではありません。
例えば外部パッケージの型がよくわからない時に使います。
以下のコードでは、strがundefinedの可能性があるので、文字列メソッドの
charAt(0)ではエラーが出ます。
export function getFirstLetter(str?: string) {
return str.charAt(0); // strがstringでないケースがあるのでエラーとなる
}
この時に、Nullとundefinedの可能性を消し去る
Non-null アサーション(非推奨)があります。
便利だと思うかもしれませんが、実際にundefinedが入ってくるとエラーになります。
export function getFirstLetter2(str?: string) {
return str!.charAt(0); // !を記述する事で、strがundefinedの可能性を消し去る処理する
}
文字列として扱いたいのであれば、if文を使いましょう。
export function getFirstLetter2(str?: string) {
if (typeof str === "string") {
return str.charAt(0);
}
}
Double アサーション(非推奨)というのもあります。
2回目のasを用いることで、任意の型に変換することができます。
使うシーンとしては、主に外部パッケージが間違っている時です。
あまり使うべきではありません。
numberだとcharAt()は使うことができませんのでエラーが出ます。
as stringだとnumberと互換性がなくエラーが出ます。
// number から型 string への変換は、互換性がないからだめ
// まず式を unknown に変換してください
export function getFirstLetter3(str: number) {
return (str as string).charAt(0);
}
そこでまず、元々numberであったstrを、一度unknownとして定義します。そして、その後にas stringを付与することで、strはunknown型に変換され、最終的にstring型となります。
export function getFirstLetter3(str: number) {
// return (str as string).charAt(0);
return (str as unknown as string).charAt(0);
}
以上となります。
次回はTypeScriptパート5です!