
TypeScript の高度な型 ⑧ 公式提唱のUtility Typesについて
TypeScript公式ドキュメントで提唱されてはいるものの、標準で組み込まれていない、便利な型定義を紹介します。
いずれも、TypeScript2.8から定義が可能になったUtility Typesです。
TypeName型
TypeName<T> はGenericsに互換性のある型が適用された場合、それに対応するString Literal Typesを返却する型
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean":
T extends undefined ? "undefined":
T extends Function ? "function" :
"object"
type T0 = TypeName<string> // "string"
type T1 = TypeName<"a"> //"string"
type T2 = TypeName<true> // "boolean"
type T3 = TypeName<() => void> //"function"
type T4 = TypeName<string[]> //"object"
FunctionalProperties型
Mapped Typesを併用して、Objectから関数型のみのプロパティ名を抽出し、その名称を元に関数型のみの新しい型を作る型です。
interface Part {
id: number;
name: string;
subparts: Part[];
updatePart(newName: string): void;
}
type FunctionPropertyName<T> = {
[K in typeof T]: T[K] extends Function ? K ; never
}[keyof T]
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>
type X = FunctionPropertyName<Part>; //"updatePart"
type Y = FunctionPropeties<Part> // {updatePart{updateName: string}: void}
NonfunctionProperties型
Mapped Types を併用してObject型から関数型以外のプロパティ名を抽出して、
その名称を元に関数型を除いた新しい型を作る型です。
interface Part [
id: number;
name: string;
subpart(newName: string); void
}
type NonFunctionPropertyName<T> = {
[K in keyof T]; T[K] extends Function ? never : K
}[keyof T]
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>
type X = NonFunctionPropertyName<Part>; //"id" | "name" | "subparts"
type Y = NonFunctionProperties<part>; // {id: number, name: string, subparts: Part[]}
Unpacked型
配列要素型、関数戻り型、promise.resolve引数型を取得する型です。
type Unpacked<T> =
T extends (infer U)[] ? U :
T extends (...args: any[]) => infer U ? U :
T extends Promise<infer U> ? U
T
type T0 = Unpacked<string> //string
type T1 = Unpacked<string[]> //string
type T2 = Unpacked<() => string> //string
type T3 = Unpacked<Promise<string>> //string
type T4 = Unpacked<Promise<string>[]> //Primise<string>
type T5 = Unpacked<unpaked<Primise<string>[]>> //string