* Ts中 extends 和 implements
* extends继承,但是不一定需要有对应的属性
* implements继承,但是一定需要有对应的属性
* as const
-
定义:常量断言【严格模式,只读属性,子属性也不可修改】,拒绝联合属性,返回类型更准确。在使用
as const后具有如下特征:- no literal types in that expression should be widened (e.g. no going from "hello" to string)【不在扩大类型,例如字符串常量"hellow"不会扩大类型到string】
- object literals get readonly properties 【对象属性变成只读,不可修改】
- array literals become readonly tuples【数组会变成只读元祖,只读,不可修改】
-
使用场景:
//1、定义一个常量,只读,不让修改 const HEADER_NAME = 'headerSlotForm' as const; //2、定义一个静态属性常量,只读,不让修改 class CustomComponentSample { public static componentName = 'CustomComponentSample' as const; } //3、A 'const' assertion can only be applied to a string, number, boolean, array, or object literal // error! let a = (Math.random() < 0.5 ? 0 : 1) as const; let b = (60 * 60 * 1000) as const; // Works! let c = Math.random() < 0.5 ? (0 as const) : (1 as const); let d = 3_600_000 as const; // arr become readonly const arr = [1, 2, 3, 4] as const // error! arr[0]=100; arr.push(1000); //5、Another thing to keep in mind is that const contexts don’t immediately convert an expression to be fully immutable. let arr = [1, 2, 3, 4]; let foo = { name: "foo", contents: arr, } as const; // error! foo.name = "bar"; foo.contents = []; // works! foo.contents.push(5); foo.contents[0] = 1000; //6、This feature means that types that would otherwise be used just to hint immutability to the compiler can often be omitted. // Works with no types referenced or declared. // We only needed a single const assertion. function getShapes() { let result = [ { kind: "circle", radius: 100 }, { kind: "square", sideLength: 50 }, ] as const; return result; } for (const shape of getShapes()) { // Narrows perfectly! if (shape.kind === "circle") { // 推导更准确,shape.radius不会报错 console.log("Circle radius", shape.radius); } else { console.log("Square side length", shape.sideLength); } } -
参考文件:
* Record
- 定义:Record<Keys, Type>
- Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.【定义一个对象,对象的key就是 Record的Keys的类型,对象的value就是 Record的type的类型】
- 应用场景:
//1、基础使用 interface CatInfo { age: number; breed: string; } type CatName = "miffy" | "boris" | "mordred"; // works!!! const cats: Record<CatName, CatInfo> = { miffy: { age: 10, breed: "Persian" }, boris: { age: 5, breed: "Maine Coon" }, mordred: { age: 16, breed: "British Shorthair" }, }; cats.boris; // error!!! 【缺少mordred属性】 const cats: Record<CatName, CatInfo> = { miffy: { age: 10, breed: "Persian" }, boris: { age: 5, breed: "Maine Coon" }, }; //2、基础使用 declare const x: Record<"a", string>; x.b; // error, Property 'b' does not exist on type 'Record<"a", string>' //3、基础使用 declare function acceptR(x: Record<"a", string>): void; acceptR({a: "hey", b: "you"}); // error, Object literal may only specify known properties acceptR({a: "hey", b: "you"}); // okay //4、基础使用 type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string> // Is it exactly the same as this?: type ThreeStringProps = {prop1: string, prop2: string, prop3: string} - 参考文献: What is the Record type?
* Pick
-
定义:Pick<Type, Keys>
- Constructs a type by picking the set of properties Keys (string literal or union of string literals) from Type.【 通过从 Type 中选择一组属性键(字符串文字或字符串文字的并集)来构造类型 】
-
应用场景:
//TS Pick 源码 type Pick< T, K extends keyof T> = { [P in K] : T[P] } //基础使用 interface Todo { title: string; description: string; completed: boolean; } type TodoPreview = Pick<Todo, "title" | "completed">; const todo: TodoPreview = { title: "Clean room", completed: false, }; todo //TodoPreview
* Omit
-
定义:Omit<Type, Keys> 【必须保证:
Keys是 keyof any(string、number、symbol)三种类型之一】- Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals). The opposite of Pick.【 通过从 Type 中剔除一组属性键(字符串文字或字符串文字的并集)来构造类型,和pick相反 】
-
应用场景:
//官方实现 type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; //自定义实现 type MyOmit<T, K extends keyof any > = { [P in keyof T as P extends K ? never : P]: T[P] }; //基础使用 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 //TodoPreview
* new 一个函数怎么定义
-
EX:
//定义 Class AAA{ constructor(param1:any,param2:any) } //使用 const instance= new AAA('1',{b:1})
* keyof
-
定义:The keyof operator takes an object type and produces a string or numeric literal union of its keys. keyof操作符 应用于对象类型,返回一个字符串或者数字式的字面量的键的并集
-
JavaScript通过 Object.keys()获取对象的所有属性键值,而typescript主要关注的是类型操作,通过 keyof 操作符可以获取对象中的所有键类型组成的联合类型。
-
应用场景:
//基础使用 type Point = { x: number; y: number }; type P = keyof Point; //"x" | "y" //进阶 type Arrayish = { [n: number]: unknown }; type A = keyof Arrayish; //number //进阶 type Mapish = { [k: string]: boolean }; type M = keyof Mapish;//【string | number】 --- ***【 Note that in this example, M is string | number — this is because JavaScript object keys are always coerced to a string, so obj[0] is always the same as obj["0"]. 】*** //高阶用法 //1、获取对象所有属性的类型 type Person = { id: number; name: string; age: number; }; type P2 = Person[keyof Person]; // number | string //解析:type P2 = Person['id' | 'name' | 'age'] = Person['id'] | Person['name'] | Person['age'] = number | string //2、获取对象所有属性的类型 type Person = { id: number; name: string; age: number; }; type MyPick<T, K extends keyof T> = { [P in K]: T[P] }; type P3 = MyPick<Person, 'id' | 'age'>//{ id: number; age: number;} //解析:K extends keyof T对K进行了约束,只能是'id','name','age'中的一个类型或者几个类型组成的联合类型;如果没有这个约束,{ [P in K]: T[P] } 则会报错。 //3、和条件类型组合实现功能 //两个对象类型合并成一个新的类型 type Person = { id: number; name: string; age: number; }; type Skill = { run: () => void; } type Merge<F extends Record<string, any>, S extends Record<string, any>> = { [P in keyof F | keyof S]: P extends keyof S ? S[P] : P extends keyof F ? F[P] : never; }; type P7 = Merge<Person, Skill>; // { id: number; name: string; age: number; run: () => void; } //解析:案例中P extends keyof S ? X : Y 的部分叫做 条件类型。代码中的含义就是如果 P是F的属性类型,则取F[P],如果P是S的属性类型,则取S[P]。 //4、和映射类型组合实现某些功能 //给对象类型的所有属性加上readonly修饰符 type Person = { id: number; name: string; age: number; }; type MyReadonly<T> = { readonly [P in keyof T]: T[P] }; type P4 = MyReadonly<Person>; // { readonly id: number; readonly name: string; readonly age: number; } //解析:T[P]是查询类型,上面介绍过了,Person['id'] 的结果是number,Person['name'] 的结果是string,Person['age'] 的结果是number。将每个属性类型添加readonly修饰符,最后的结果就是 { readonly id: number; readonly name: string; readonly age: number; } //5、和映射类型组合实现某些功能 //去掉对象类型的某些属性【微软官是通过Pick 和exclude组合来实现Omit逻辑的,我们可以通过以下的代码实现同样的功能。】 type Person = { id: number; name: string; age: number; }; type MyOmit<T, K> = { [P in keyof T as P extends K ? never : P]: T[P] }; type P5 = MyOmit<Person, 'id' | 'name'> // {age: number;} //解析:代码中的as P extends K ? never : P这部分代码叫做重映射 ,因为我们不一定需要的是P,有些情况下需要对P进行一些转换;案例中K 中包含的P键值类型则通过never忽略了,相反则保留。所以最后的结果是{age: number;} //6、和映射类型组合实现某些功能 //给对象类型添加新的属性 type Person = { id: number; name: string; age: number; }; type AppendToObject<T, U extends keyof any, V> = {[P in keyof T | U]: P extends keyof T ? T[P] : V} type P6 = AppendToObject<Person, 'address', string> // { address: string; id: number; name: string; age: number; } //解析:代码中的U extends keyof any,为新的键,P extends keyof T 条件类型,如果P是Person的键值类型,则取 T[P],否则则取V //7、keyof any type KEY = keyof any //即 string | number | symbol
* never 类型判断时会被忽略
- EX:
type T = P extends K ? never : P //T的类型可能是undefined