TypeScript provides several utility types to facilitate common type transformations. These utilities are available globally.
TypeScript 内置了一些功能类型来更容易对普通类型的转换,可以全局使用。
Partial
作用:让所有类型都变成可选
origin code
/*** Make all properties in T optional*/type Partial<T> = {[P in keyof T]?: T[P];};
Mapped Types:映射类型是一种泛型类型,它使用PropertyKeys的联合(通常keyof创建)来迭代键以创建类型
type OptionsFlags<Type> = {[Property in keyof Type]: boolean;};
源码的实现就是使用映射类型创建每一个属性,然后将T中的每个属性变为可选
eample
interface partialObj {name: stringage: number | stringinfoMyself: string}function undateObj(person: Partial<partialObj>) {return person}const obj = undateObj({ // Successname: '老王',age: '问就是18',})
Requirec
作用:让所有类型都变成必需,与Partial
origin code
/*** Make all properties in T required*/type Required<T> = {[P in keyof T]-?: T[P];};
eample
interface Props {a?: number;b?: string;}const obj: Props = { a: 5 };const obj2: Required<Props> = { a: 5 };//Error Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.
Readonly
作用:让T中的每一个属性都变为可读,不可再重新分配
origin code:
/*** Make all properties in T readonly*/type Readonly<T> = {readonly [P in keyof T]: T[P];};
在Mapped types 上添加关键字readonly,
example:
interface Todo {title: string;}const todo: Readonly<Todo> = {title: "Delete inactive users",};todo.title = "Hello";//Error Cannot assign to 'title' because it is a read-only property.
Record
origin code:
/*** Construct a type with a set of properties K of type T*/type Record<K extends keyof any, T> = {[P in K]: T;};
将K中的每个属性([P in K]),都转为T类型
example
interface CatInfo {age: number;breed: string;}type CatName = "miffy" | "boris" | "mordred";const cats: Record<CatName, CatInfo> = {miffy: { age: 10, breed: "Persian" },boris: { age: 5, breed: "Maine Coon" },mordred: { age: 16, breed: "British Shorthair" },};
例子中CatName中的每一个属性都变成了CatInfo类型
Pick
origin code:
/*** From T, pick a set of properties whose keys are in the union K*/type Pick<T, K extends keyof T> = {[P in K]: T[P];};
通过从T中选取一组属性Keys来构造类型Type。 K extends keyof T 表示K中的每一个属性都来自T
example:
interface Todo {title: stringdescription: stringcompleted: boolean}type TodoPreview = Pick<Todo, 'title' | 'completed'>const todo: TodoPreview = {title: 'Clean room',completed: false,}/*** interface TodoPreview {description: stringcompleted: boolean}*/
Exclude
origin code
从 T 中排除那些可分配给 U 的类型
/*** Exclude from T those types that are assignable to U*/type Exclude<T, U> = T extends U ? never : T;
T extends U ? never : T 可理解为T是否是U的派生类 是的话则never,不是则为T
never:表示永远不存在的值的类型。
类似(a + b) * c => ac + bc
example
type T0 = Exclude<"a" | "b" | "c", "a">;type T0 = "b" | "c"//相当于 <"a","a"> | <"b","a"> | <"c","a">type T1 = Exclude<"a" | "b" | "c", "a" | "b">;type T1 = "c"type T2 = Exclude<string | number | (() => void), Function>;type T2 = string | number
complex example
// 比如后端接口定义好的返回类型是这个,但是我们并不能直接修改interface Api {name: stringage: numbercontent: string}// error: Types of property 'name' are incompatible.interface CustomApi extends Api {name: number;}// changeinterface CustomApi1 extends Pick<Api, 'age'> {name: number;}// 但是上面还是太复杂了,你需要把所有属性挑拣起来,结合 Exclude 将key全拿出来 可以省事很多interface CustomApi2 extends Pick<Api, Exclude<keyof Api, 'name'>> {name: number;}// Error 类型“{ name: number; }”缺少类型“CustomApi2”中的以下属性: age, contentconst api2: CustomApi2 = {name: 2,}
Extract
origin code
通过从Type可分配给 的所有联合成员中提取来构造一个类型Union。
/*** Extract from T those types that are assignable to U*/type Extract<T, U> = T extends U ? T : never;
取T和U的交集
example:
type union = Extract<'a' | 'b' | 'c' | 'd', 'b' | 'f'>f// union = 'b'
Omit
origin code
/*** Construct a type with the properties of T except for those in type K.构造一个除类型K之外的T属性的类型*/type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
example
interface Todo {title: string;description: string;completed: boolean;createdAt: number;}type TodoPreview = Omit<Todo, "description">;const todo: TodoPreview = {title: "Clean room",completed: false,createdAt: 1615544252770,};todo;const todo: TodoPreviewtype TodoInfo = Omit<Todo, "completed" | "createdAt">;const todoInfo: TodoInfo = {title: "Pick up kids",description: "Kindergarten closes at 5pm",};
NonNullable
origin code
从T中排除null和undefined并重新构造一个类型
/*** Exclude null and undefined from T*/type NonNullable<T> = T extends null | undefined ? never : T;
example
type T0 = NonNullable<string | number | undefined>;//type T0 = string | number
complex example
//若想要接口中每个属性都去除 null | undefinedinterface info {name?:string | nullage?: number | null}type enableNonNullable<T> = {[P in keyof T]-?: NonNullable<T[P]>}
