容易忽略的关键字 typeof 关键字 Typescript 可以使用typeof关键字作为类型保护, 同样的和js一样还存在 instanceof、 in 等关键字
ts中通过typeof 类可以获得类的类类型,直接使用类作为类型此时使用的是类的实例类型。
更多的信息: 查看官方文档https://www.typescriptlang.org/docs/handbook/2/typeof-types.html
const school = "school" let n : typeof schoolfunction f ( ) { return { x : 10 , y : 3 } } type P = ReturnType <typeof f>
keyof 关键字 keyof操作符会将一个对象类型(注意这里是类型并不是值)的key组成联合类型返回。
有点 Object.keys(obj) 的意思,只不过要关注的是,这里是取出所有的key做联合(a | b | c)
type ArrayIsh = { [n : number ]: unknown };type A = keyof ArrayIsh ; type MapIsh = { [k : string ]: boolean };type M = keyof MapIsh ;
而 keyof 与 in 关键字组合起来,就可以复制一个类型(额,只是为了演示,实际开发大可不必)
interface Test { t : string k : number } type Copy <T> = { [K in keyof T]: T[K] } type CopyTest = Copy <Test >const fff : CopyTest = { t : "1" , k : 1 }
extends 关键字 Ts中extends除了用在继承上,还可以表达泛型约束,通过extends关键字可以约束泛型具有某些属性。
function loggingIdentity<T>(arg : T): T { console .log (arg.length ) return arg } interface Lengthwise { length : number } function loggingIdentity<T extends Lengthwise >(arg : T): T { console .log (arg.length ) return arg } loggingIdentity (3 ); loggingIdentity ({length : 10 , value : 3 }) function getProperty<T, K extends keyof T>(obj : T, key : K): T[K] { return obj[key] } const x = {a : "zz" , b : 2 , c : 3 , d : {test : 1 }}getProperty (x, "a" ) getProperty (x, "e" )
infer(推断的意思) 关键字 表示在 extends 条件语句中 待推断的类型变量
, 必须联合 extends 出现
注意⚠️: infer 跟随 extends 成对出现, infer 表示待推断
使用
type ParamType <T> = T extends (...args : infer P) => any ? P : T;interface User { name : string ; age : number ; } type Func = (user: User ) => void ;type Param = ParamType <Func >; type AA = ParamType <string >;
内置类型 partial 部分的, 局部的 作用: 将对象的第一层属性转为可选的
如果有很多属性树非必需的,那么可以采用这个一次性全部转了
根据这个描述,其实partial的原理非常的简单
type Partial <OBJ > = { [key in keyof OBJ ]?: OBJ [key] }
interface Coord = { x : number , y : number , obj : { t : string } } type Coord2 = partial<Coord >interface Coord3 { x?: number | undefined , y?: number | undefined , obj?: { t : string } | undefined } interface Person { name : string age : number detail : { school : string company : string } } type DeepPartial <T> = { [K in keyof T]?: T[K] extends object ? DeepPartial <T[K]> : T[K] } type DPerson = DeepPartial <Person >
Required Required全部的意思, 在ts 中表示将 全部的属性转为必选的。 与Partial 意思刚好相反,同样不支持深层属性,需要递归。
type Req <T> = { [K in keyof T]-?: T[K] }
-?
什么东西?
没错, 正是通过在属性后面采用 -? 定义属性为必填的。
对于深层的属性,同样的采用递归的方式来实现
type DeepRequired <T> = { [K in keyof T]-?: T[K] extends object ? DeepRequired <T[K]> : T[K]; }
例子不举了
Exclude<T,U> 排除 T 类型中满足 U 的类型从而返回新的类型。 主要是针对于 联合类型(string|number|array)
来操作。
简单说就是: 排除 T 中包含的 U 部分, 返回 剩下没排除的。
let a : string | number ; type CustomType = Exclude <typeof a, string >;
原理实现: 泛型 配合 extend 已经条件运算符
type Exclude <T, U> = T extends U ? never : T
extract 的含义与 exclude 相反, 他会挑出 T 中符合 U 的类型, 而非排除
let a : string | number ; type CC = Extract <typeof a, number | Array <number >>const c : CC = [12 ]
Pick<Type,Keys> 关键字 pick: 挑选的意思
从 type中挑选出 keys, 从而返回新的类型
interface Props { name : string , label : number , value : boolean } type ChildrenProps = Pick <Props , 'name' | 'label' >
原理实现
type Pick <T, K extends keyof T> = { [P in K]: T[P] }
Parameters<T,> Parameters<T,> 用于获取函数的参数类型组成的元组类型[a:string, b:number]
const fn = (a:string , b: number , ...c: number [] ) => {}type c = Parameter <typeof fn>
源码实现:
type Parameters <T extends (...args :any ) => any > = T extends (args : infer P) => any ? P : never
Omit<T,K> 关键字 omit: 忽略的意思
从另一个对象类型中剔除某些属性,并创建一个新的对象类型。
type User = { id : string , name : string , email : string } type UserWithoutEmail = Omit <User , 'email' >type UserWithoutEmail = { id : string , name : string }
ReturnType<T,> 接受传入一个函数类型为泛型,返回值为函数的返回类型
type T0 = ReturnType <() => string >; type T1 = ReturnType <(s: string ) => void >;
Record<Keys,type> 关键字 构造一个新的对象类型,其属性键为Keys(联合类型),属性值为Type。
type keys = 'name' | 'title' | 'hello' interface value { name : string , label?: number } const b : Record <keys, value> = { name : { name : 'ww' , label : 1 }, title : { name : 'ls' , label : 2 }, hello : { name : 'zs' } } function mapping<K extends string | number | symbol , V, R>( obj : Record <K, V>, callback : (key: K, value: V ) => R ): Record <K, R> { const result = {} as Record <K, R> Object .keys (obj).forEach (key => { const parseKey = key as K const value = obj[parseKey] result[parseKey] = callback (parseKey, value) }) return result } mapping ({name : "19" , company : "Tc" }, (key, value ) => { return key + value })