只会作用于obj原本属性,不会引入新的属性
通过Readonly
关键字实现
tsinterface Prople {
name: string
age: number
}
type myPeople = Readonly<Prople>
/*
type myPeople = {
readonly name: string;
readonly age: number;
}
*/
通过关键字Partial
实现
tsinterface Prople {
name: string
age: number
}
type myPartial = Partial<Prople>
/*
type myPartial = {
name?: string | undefined;
age?: number | undefined;
}
*/
tstype Partial<T> = {
[P in keyof T]?: T[P];
};
/*
Partial<T>: T 表示泛型
keyof T: 索引类型的查询操作符,返回类型T的所有公共属性字面量构成的联合类型
in 操作符: 用于判断某个属性是否在指定对象或其原型链中,如果存在则in运算符返回true
*/
// EG:
interface A {
id:string,
name:string
}
type D = Partial<A>
/*
type Partial<T> = {
[P in keyof T]?: T[P];
};
*/
/*
keyof T : 索引类型的查询操作符,表示类型A的所有公共属性的字面量构成的联合类型
*/
// keyof A : 'id' | 'string'
let B:keyof A = 'id' // sure
B = 'name' // sure
// B = 'age' // Type '"age"' is not assignable to type 'keyof A'.
/*
in 操作符: 用于判断某个属性是否在指定对象或其原型链中,如果存在则in运算符返回true
*/
和Partial
相反,用于让可选属性变为必选属性, 通过Required
实现
tsRequired<T>
tstype Required<T> = {
[P in keyof T]-?: T[P];
};
条件类型是一种由条件表达式决定的类型
实现类型过滤
若类型T可以被赋值给类型U,那么结果类型为X类型,否则为Y类型
tsT extends U ? X : Y
tstype TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T1 = TypeName<string>//T1类型为字面量类型"string"
若类型T可以被赋值给类型U,那么结果类型为X类型,否则为Y类型
ts(A | B) extends U ? X : Y
//相当于
(A extends U ? X : Y) | (B extends U ? X : Y)
tstype TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T3 = TypeName<string | string[]>//TS类型为字面量类型"string"和字面量类型"object"的联合类型
从T
中选择部分类型组合成新类型
tsPick<T, K>
tstype Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
/*
K extends keyof T: K继承于类型T的所有字面量类型构成的联合类型
*/
构造一个对象类型,其属性key
是Keys
,属性value
是Type
,被用于映射一个类型的属性到另一个类型
第一个参数接受预定义的新的属性,第二个参数接受已知的类型
tsinterface Prople {
name: string
age: number
}
type myRecord = Record<"x"|"y",Prople>
/*
type myRecord = {
x: Prople;
y: Prople;
}
*/
tstype Record<K extends keyof any, T> = {
[P in K]: T;
};
从类型T
中过滤掉可以赋值给类型U
的类型
tsExclude<T,U>
tstype Diff<T, U> = T extends U ? never : T
/*
// Diff被拆解为多个类型的联合类型
// Diff<"a", "a" | "e"> | Diff<"b", "a" | "e"> | Diff<"c", "a" | "e">
// 字面量类型"a"可以被赋值给字面量联合类型"a" | "e",所以返回never
// 字面量类型"b"无法被赋值给字面量联合类型"a" | "e",所以返回字面量类型"b"
// 字面量类型"c"无法被赋值给字面量联合类型"a" | "e",所以返回字面类类型"c"
// never | "b" | "c"
//最后类型为 "b" | "c"
*/
tstype A = 'id' | 'name'
type B = 'id' | 'name' | 'age'
const D:Exclude<B,A> // 类型为'age'
与Exclude
相反,从类型T
中抽取出可以赋值给类型U
的类型
tsExtract<T,U>
tstype Extract<T, U> = T extends U ? T : never;
tstype A = 'id' | 'name'
type B = 'id' | 'name' | 'age'
const D:Extract<B,A> // 类型为"id" | "name"
省略,传入一个类型,和此类型的几个属性,把传入的属性省略掉,剩余的类型组合为一个新类型
tsOmit<T,U>
tstype Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
ts// type A = keyof any //类型为: string | number | symbol
// type B = never | null
// type C = B extends A ? 'yes' : 'no'; // 'yes'
interface A {
name: string;
age: number;
id: number;
}
type B = 'name' | 'age'
const C: Omit<A, B> = { 'id':2233 }
/*
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
*/
// keyof any: string | number | symbol
// K extends keyof any: 泛型k必须可以赋值给`string | number | symbol`构成的联合类型
/*
Pick<T, Exclude<keyof T, K>>;
*/
/*
Exclude<keyof T, K>
keyof T: 'name' | 'age' | 'id'
故而:
Exclude<keyof T, K>: 'id'
*/
/*
Pick<T, Exclude<keyof T, K>>变成了: Pick<T,'id'>
即根据Pick的定义,会从此处例子中的类型A中抽取属性'id'组成新的类型
*/
过滤掉null
类型和undefined
类型
tsNonNullable<T>
ts// 方法一
type NonNullable<T> = T & {}
/*
{}:排除了null和undefined以外的任何类型
T & {}: 返回的是类型T与{}的交叉类型
*/
// 方法二
type NonNullable<T> = T extends null | undefined ? never : T;
获取传入函数的参数组成的类型
tsParameters<T>
tstype Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never
ts// 通过接口约束函数
interface myTtest {
(x:number,y:number):number
}
let myFunction:myTtest= function(x,y){return x+y}
console.log(myFunction(1,2))
const user: Parameters<myTtest> = [1,2]// [x: number, y: number]
获取传入的构造函数的参数组成的类型
tsConstructorParameters<T>
tstype ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never
tsinterface A {
name: string;
age: number;
}
interface B {
new (name: string, age: number): A
}
const C: ConstructorParameters<B> = ['1',2]// [name: string, age: number]
可以获取函数返回值类型,接受一个函数作为参数
tsReturnType<Fnction>
tstype ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
tstype TB = ReturnType<() => string>
//TB类型为string类型
获取构造函数、实例的返回类型
tsInstanceType<T>
tstype InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
tsconst user = class {
name: string;
age: number;
constructor (name: string, age: number) {
this.name = name
this.age = age
}
showInfo () {
console.log('name: ', this.name, 'age: ', this.age);
}
}
const user1: InstanceType<typeof user> = new user('张三', 20)
// const user2: user = new user('张三', 20) // Error: user作为值,此处却用为类型
转大写
tsUppercase<T>
tstype Uppercase<S extends string> = intrinsic;
tstype userinfo = 'name' | 'age' | 'id'
let userID: Uppercase<userinfo> = 'ID' // "NAME" | "AGE" | "ID"
转小写
tsLowercase<T>
tstype Lowercase<S extends string> = intrinsic
tstype userinfo = "NAME" | "AGE" | "ID"
let userID: Lowercase<userinfo> = 'id' // "name" | "age" | "id"
首字母大写
tsCapitalize<T>
tstype Capitalize<S extends string> = intrinsic
tstype userinfo = "name" | "age" | "id"
let userID: Capitalize<userinfo> = 'Id' // "Name" | "Age" | "Id"
首字母小写
tsUncapitalize<T>
tstype Uncapitalize<S extends string> = intrinsic
tstype userinfo = "Name" | "Age" | "Id"
let userID: Uncapitalize<userinfo> = 'id' // "name" | "age" | "id"
本文作者:RKLS
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!