TypeScript之高级工具类型

107 阅读2分钟

Record

将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型

type Record<K extends keyof any, T> = { [P in K]: T }
interface EmployeeType {
    id: number
    fullname: string
    role: string
}
 
let employees: Record<number, EmployeeType> = {
    0: { id: 1, fullname: "John Doe", role: "Designer" },
    1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
    2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}

Partial

将传入的属性变为可选项

type Partial<T> = { [P in keyof T]?: T[P] }
interface EmployeeType {
    id: number
    fullname: string
    role: string
}
 
let employees: Partial<EmployeeType> = {
    id: 123
}

Required

将传入的属性都变为必选项

type Required<T> = { [P in keyof T]-?: T[P] }
interface EmployeeType {
    id?: number
    fullname?: string
    role?: string
}
 
let employees: Partial<EmployeeType> = { 
    id: 1, 
    fullname: "John Doe", 
    role: "Designer" 
}

Readonly

表明特定类型是只读的。

type User = { 
    firstName: string, 
    lastName: string 
} 
let firstUser:Readonly<User> = { 
    firstName: "John", 
    lastName: "Doe" 
}

如果您尝试更改 的属性firstUser,您将收到以下错误:

Cannot assign to 'firstName' because it is a read-only property.

Mutable

将 T 的所有属性的 readonly 移除

type Mutable<T> = { 
    -readonly [P in keyof T]: T[P] 
}

Extract

从联合类型中提取特定元素

type Extract<T, U> = T extends U ? T : never;
type myUnionType = "🥒" | "🥔" | "🌶" | "🌽" 
let myFirstVariable:Extract<myUnionType, "🥒" | "🥔"> = "🥒" 
    // ^ 
    // └ - - Type is "🥒" | "🥔"

Exclude

从已定义的联合类型中排除某些成员

type Exclude<T, U> = T extends U ? never : T;
type myUnionType = "🍇" | "🍎" | "🫐" | "🍋"
let noApplesOrLemons:Exclude<myUnionType, "🍋" | "🍎"> = "🍇"; 
    // ^ 
    // └ - - Type is "🍇" | "🫐"

Omit

从对象属性里面排除某一个或几个属性

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type User = {
  firstName: string;
  lastName: string;
  age: number;
  lastActive: number;
}
 
type UserNameOnly = Omit<User, "age" | "lastActive">
type UserNameAndActive = Omit<User, "age">

const userByName:UserNameOnly = {
    firstName: "John",
    lastName: "Doe",
};
const userWithoutAge:UserNameAndActive = {
    firstName: "John",
    lastName: "Doe",
    lastActive: -16302124725
}

Pick

从对象属性里面提取某一个或几个属性

type Pick<T, K extends keyof T> = { [P in K]: T[P] }
type User = { 
    firstName: string, 
    lastName: string, 
    age: number 
} 

type UserAge = Pick<User, "age"> 

let age:UserAge = { 
    age: 1534 
}

Parameters

基于函数,创建参数的元组类型

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
const myFunction = (a: string, b: string) => { 
    return a + b; 
} 

type myType = Parameters<typeof myFunction> 

let myArray:myType = [ 'hello ', 'world' ]; 
myFunction(...myArray)

ReturnType

获取函数的返回输出,并基于它构造一个类型

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
function sendData(a: number, b: number) { 
    return { a: `${a}`, b: `${b}` } 
} 
type Data = ReturnType<typeof sendData> 
// The same as writing: 
// type Data = { // a: string, // b: string // }

NonNullable

过滤掉联合类型里的nullundefined

type NonNullable<T> = T & {};
type myType = string | number | null | undefined 
type noNulls = NonNullable<myType>

在上面的示例中,noNullsnow 的类型为string | number