「这是我参与2022首次更文挑战的第39天,活动详情查看:2022首次更文挑战」。
赋值推断
赋值时推断,类型从右向左流动,会根据赋值推断出变量类型
let str = "dafei";
let age = 18;
let boolean = true;
返回值推断
自动推断函数返回值类型
function sum(s:string,b:string){
return a + b;
// 函数返回值会自动推断出返回值的类型
}
sum("a","b")
函数推断
函数从左到右进行推断
type Sum = (a:string,b:string) => string;
const sum:Sum = (a,b) => a + b;
属性推断
可以通过属性值,推断出属性的类型
let obj = {
name:'dafei',
age:18
}
let {name,age} = obj;
类型反推断
可以使用
typeof关键字进行反推断变量类型
let obj = {
name:"dafei",
age:18
}
let obj2 = typeof obj
索引访问操作符
interface IPerson {
name:string,
age:number,
job:{
address:string
}
}
type job = IPerson['job']
类型映射
interface IPerson {
name:string,
age:number
}
type MapPerson = {[key in keyof IPerson]:IPerson[key]}
交叉类型
交叉类型(Intersection Types)是将多个类型合并为一个类型
举例:我们提供两拨人,一拨人都很帅、另一拨人很高。我们希望找到他们的交叉部分 => 又高又帅的人
interface Person1 {
handsome: string,
}
interface Person2 {
high: string,
}
type P1P2 = Person1 & Person2;
let p: P1P2 = { handsome: '帅', high: '高' }
- 交叉类型
function mixin<T, K>(a: T, b: K): T & K {
return { ...a, ...b }
}
const x = mixin({ name: 'df' }, { age: 18 })
interface IPerson1 {
name:string,
age:number
}
interface IPerson2 {
name:number
age:number
}
type person = IPerson1 & IPerson2
let name!:never
let person:person = {name,age:11}; // 两个属性之间 string & number的值为never
条件类型
条件类型的基本使用
可以使用
extends关键字和三元表达式,实现条件判断
interface Fish {
name1: string
}
interface Water {
name2: string
}
interface Bird {
name3: string
}
interface Sky {
name4: string
}
type Condition<T> = T extends Fish ? Water : Sky;
let con1: Condition<Fish> = { name2: '水' }
条件类型分发
let con2: Condition<Fish|Bird> = { name2: '水' }
这里会用每一项一次进行分发,最终采用联合类型作为结果等价于:
type c1 = Condition<Fish>;
type c2 = Condition<Bird>;
type c = c1 | c2
内置条件类型
Exclude排除类型
type Exclude<T, U> = T extends U ? never : T;
type MyExclude = Exclude<'1' | '2' | '3', '1' | '2'>
Extract抽取类型
type Extract<T, U> = T extends U ? T : never;
type MyExtract = Extract<'1' | '2' | '3', '1' | '2'>
NoNullable非空检测
type NonNullable<T> = T extends null | undefined ? never : T
type MyNone = NonNullable<'a' | null | undefined>
infer类型推断
ReturnType返回值类型
function getUser(a: number, b: number) {
return { name: 'zf', age: 10 }
}
type ReturnType<T> = T extends (...args: any) => infer R ? R : never
type MyReturn = ReturnType<typeof getUser>
Parameters参数类型
type Parameters<T> = T extends (...args: infer R) => any ? R : any;
type MyParams = Parameters<typeof getUser>;
ConstructorParameters构造函数参数类型
class Person {
constructor(name: string, age: number) { }
}
type ConstructorParameters<T> = T extends { new(...args: infer R): any } ? R : never
type MyConstructor = ConstructorParameters<typeof Person>
InstanceType实例类型
type InstanceType<T> = T extends { new(...args: any): infer R } ? R : any
type MyInstance = InstanceType<typeof Person>
infer实践
将数组类型转化为联合类型
type ElementOf<T> = T extends Array<infer E> ? E : never;
type TupleToUnion = ElementOf<[string, number, boolean]>;
将两个函数的参数转化为交叉类型
type T1 = { name: string };
type T2 = { age: number };
type ToIntersection<T> = T extends ([(x: infer U) => any, (x: infer U) => any]) ? U : never;
type t3 = ToIntersection<[(x:T1)=>any,(x:T2)=>any]>
表示要把T1、T2赋予给x,那么x的值就是T1、T2的交集。(参数是逆变的可以传父类)
TS的类型:TS主要是为了代码的安全性来考虑。所以所有的兼容性问题都要从安全性来考虑!