Open1
[読書メモ]プロを目指す人のためのTypeScript入門 安全なコードの書き方から高度な型の使い方まで(ISBN: 978-4-297-12747-3)
6章 高度な型
- ユーザ定義型ガードを使えば、引数に与えられた値が特定の型であることを示すことができる。
// 引数名 is 型という書き方をする。返り値はbooleanになる。
function isStringOrNumber(value: unknown): value is string | number {
return typeof value === 'string' || typeof value === 'number';
}
const something: unknown = 123;
if (isisStringOrNumber(something)) {
// NOTE: somethingがstring型あるいはnumber型として扱うことができる
console.log(something.toString());
}
function isStringOrNumber(value: unknown): boolean {
return typeof value === 'string' || typeof value === 'number';
}
const something: unknown = 123;
if (isisStringOrNumber(something)) {
// NOTE: コンパイルエラーが出る
console.log(something.toString());
}
- ただし、ユーザ定義型ガードは自分で書く必要があり、実装にミスがあると型安全性を破壊し得る危険性があるので注意
6.8 力試し
type Some<T> = {
tag: 'some',
value: T
};
type None = {
tag: "none"
};
type Option<T> = Some<T> | None;
const showNumber = (value: Option<number>): void => {
if (value.tag === 'some') {
console.log(value.value);
} else {
console.log('nothing');
}
};
// ユーザ定義型ガードを使ってtagがsomeかどうか判定する
function isSome<T>(obj: Option<T>): obj is { tag: 'some', value: T } {
if (obj == null) return false;
return (obj.tag === 'some');
}
// objのtagがsomeの時は値を出力する
function showNumberIfExists(obj: Option<number>) {
if (isSome(obj)) {
console.log(obj.value);
}
}
function mapOption<T, U>(obj: Option<T>, callback: (value: T) => U): Option<U> {
switch (obj.tag) {
case "some":
return { tag: "some", value: callback(obj.value) };
case "none":
return { tag: "none" };
}
}
- キーワード
- ユニオン型・インターセクション型・リテラル型・型の絞り込み(typeof)・keyof型(keyof T)・lookup型(T[K])・ユーザ定義型ガード・mapped types({[P in K]: T} Pか型変数)・condtitional types(X extends Y ? S :T)・組み込み型