
// keyof
interface Person {
name: string;
age: number;
location: string;
}
type PersonKeys = keyof Person; // type PersonKeys = "name" | "age" | "location"
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person = { name: 'zhangsan', age: 18, location: 'beijing' };
const name = getProperty(person, 'name');// extends
// 类型约束
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T) {
return arg.length; // 属性“length”在类型“T”中不存在。
}
logLength("Hello"); // OK
logLength([1, 2, 3]); // OK
logLength(123); // 错误:number 类型没有 length 属性
// 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
type ToArray<T> = T extends any ? T[] : never;
type StrOrNum = ToArray<string | number>; // string[] | number[]
// 类继承/类型组合
interface ChildComponentProps {
onChange: (val: string)=> void
}
interface ChildComponentProps2 {
onReset: (value: string)=> void
}
interface ParentComponentProps extends ChildComponentProps, ChildComponentProps2 {
value: string
}// infer 用于在条件中推断类型,它允许我们从现有类型中提取类型信息
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function getMessage(): string {
return 'hello';
}
type MessageType = ReturnType<typeof getMessage>; // string在ts中,泛型工具类型 Record<K, T> 主要用于创建一个给定键类型K映射到值类型T的新类型。该类型的键名由 K 类型决定,而每个属性值则由 T 类型决定
源码
type Record<K extends keyof any, T> = {
[P in K]: T;
}基本用法
// 假设我们有一个字符串数组,表示一些颜色的名字,我们可以定义一个类型来存储这些颜色对应的十六进制值
type ColorNames = 'red' | 'green' | 'blue';
type HexColorCode = string;
const colorMap: Record<ColorNames, HexColorCode> = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
};
// 结合枚举使用
enum StatusCodes {
OK = 200,
NOT_FOUND = 404,
INTERNAL_SERVER_ERROR = 500,
}
type StatusCodeMessage = string;
const statusMessages: Record<StatusCodes, StatusCodeMessage> = {
StatusCodes.OK: 'OK',
StatusCodes.NOT_FOUND: 'Not Found',
StatusCodes.INTERNAL_SERVER_ERROR: 'Internal Server Error',
};注意事项
Record<K, T> 时,每个键应该是唯一的,不能重复。如果重复了,后面的键值对会覆盖前面的键值对Record<K, T> 创建的对象类型只能包含指定键的属性,不允许存在其他未定义的属性Record<K, T> 创建的对象类型,如果键包含可选属性,生成的新类型的属性都是必选的。在ts中,泛型工具类型 Partial<T> 主要用于将一个类型的所有属性都变为可选属性。
源码
type Partial<T> = {
[P in keyof T]?: T[P];
};使用场景
interface Foo {
name: string
age: number
}
type Bar = Partial<Foo>
// 相当于
type Bar = {
name?: string
age?: number
}
生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项
源码
type Required<T> = {
[P in keyof T]-?: T[P];
};interface Foo {
name: string;
age?: number;
}
type Bar = Required<Foo>
// 相当于
type Bar = {
name: string;
age: number;
}生成一个新类型,T 中的 K 属性是只读的,K 属性是不可修改的
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};interface Foo {
name: string
age: number
}
type Bar = Readonly<Foo>
// 相当于
type Bar = {
readonly name: string
readonly age: number
}生成一个新类型,映射类型 ; P in K 类似于 js的 for…in语句 ; extends 为泛型约束
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}interface Foo {
name: string
age: number
gender?: string
}
type Bar = Pick<Foo, 'name' | 'age'>;
// 相当于
type Bar = {
name: string
age: number
}type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>type Foo = {
name: string;
age: number;
}
type Bar = Omit<Foo, 'name'>;
// 相当于
type Bar = {
age: number;
}// Exclude用于从类型 T 中排除可以赋值给类型 U 的类型
type Exclude<T, U> = T extends U ? never : T;
// 如果 T 是 U 的子类型则返回 never 不是则返回 Ttype A = number | string | boolean;
type B = number | boolean;
type FOO = Exclude<A, B>;
// 相当于
type FOO = string;// Extract用于从类型 T 中提取可以赋值给类型 U 的类型
type Extract<T, U> = T extends U ? T : never;type A = number | string | boolean
type B = number | boolean
type FOO = Extract<A, B>
// 相当于
type FOO = number | boolean从泛型 T 中排除掉 null 和 undefined
NonNullable<T>type NonNullable<T> = T extends null | undefined ? never : T;
type t = NonNullable<'name' | null | undefined>;
/* type t = 'name' */Parameters<T> 是 TypeScript 中的一个实用工具类型,用于获取函数类型的参数类型数组。它以元组的形式返回函数参数的类型
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
type t = Parameters<(name: string) => any>; // type t = [string]
type t2 = Parameters<((name: string) => any) | ((age: number) => any)>; // type t2 = [string] | [number]以元组的方式获得构造函数的入参类型
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
type t = ConstructorParameters<(new (name: string) => any) | (new (age: number) => any)>;
// type t = [string] | [number]获得函数返回值的类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
type t = ReturnType<(name: string) => string | number>
// type t = string | number获得构造函数返回值的类型
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
type t = InstanceType<new (name: string) => {name: string, age: number}>
/*
type h = {
name: string;
age: number;
}
*/