typescript学习:关键字,操作符,keyof,in,infer...

本文内容如下

关键字,操作符

如果你都有了答案,可以忽略本文章,或去TS学习地图寻找更多答案


关键字操作符

typeof

JS中的typeof:在运行时判断类型

TS中的typeof:在编译时获取类型

interface Person {
    name: string,
    age: number,
}

let person: Person = { name: 'tao', age: 18 }

//两者一样
type p1 = typeof person  
type p2 = Person

in:遍历

type Names = "xiaoming" | "zhangsan"

type Obj = {
    [k in Names]: k
}

Obj = {
	xiaoming: 'xiaoming',
	zhangsan: 'zhangsan'
}

keyof

作用: 获取类,对象,接口的所有属性名组成的 联合类型

// 接口
interface Person {
    name: string;
    age: number;
}
type K1 = keyof Person;   // "name" | "age"
type K2 = keyof Person[]; // "length" | "toString" | "pop" | "push" | "concat" | "join" 


// 对象
let obj = { name: 'tao', age: 18 }
// type newobj = typeof obj
// type keyofObj = keyof newobj  //name | age

type keyofObj = keyof typeof obj  //简写 name | age
let newObj1: keyofObj = 'name'    //通过
let newObj2: keyofObj = 'namexx'  //报错


// 类
class User {
    constructor(public username: string, public age: number) { }
}
type UserType = keyof User  //username | age

let userValue: UserType = 'username' //通过

infer

占位符式的关键字

注意:学习该知识需要先学习泛型

表示在 extends 条件语句中以占位符出现的用来修饰数据类型的关键字,被修饰的数据类型等用到的时候才能被推断出来

作用: 获取参数,返回值,泛型 的类型

出现位置

  1. 参数
  2. 返回值
  3. 类型的泛型具体化类型上

例子1:出现位置在参数上

interface Customer {
    custname: string
    buymoney: number
}

需求:获取custFuncType的参数类型
type custFuncType = (cust: Customer) => string

实现:
type inferType<T> = T extends (parmas: infer P) => any ? P : T

type inferReusltType = inferType<custFuncType>  //Customer类型



//详解
type inferType<T> = T extends (parmas: infer P) => any ? P : T

传递泛型后等于:
type inferType<custFuncType> = (cust: Customer) => string extends (parmas: infer P) => any ? P : (cust: Customer) => string

解释:
(cust: Customer) => string 的类型是否与 (parmas: infer P) => any 相同, 如果相同,返回P(这个P已经变成了Customer,这就是infer的作用,作为占位符使用), 如果不同返回原来的表达式
在这个例子中,是相同的,因为any 是任何类型的子类或父类,肯定包括string, 所以返回P,也就是Customer

相反的例子

type custFuncType = (cust: Customer, str: string) => string
type inferType<T> = T extends (parmas: infer P) => any ? P : T
type inferReusltType = inferType<custFuncType>   //custFuncType类型

(cust: Customer, str: string) => string  (parmas: infer P) => any 不符合,所以返回(cust: Customer, str: string) => string
因为(cust: Customer, str: string) => string是两个参数, (parmas: infer P) => any 是一个参数

例子2:出现位置在参数上

注意infer的写法,inter获取返回值,它返回什么,是后面的三元表达式决定

type custFuncType = (cust: Customer) => string
type inferType<T> = T extends (parmas: any) => infer P ? P : T
type inferReusltType = inferType<custFuncType>  //string类型

例子3:类型的泛型具体化类型上

class Subject {
    constructor(public subname: string) { }
}

let chineseSubject = new Subject('语文')
let englishSubject = new Subject('英文')
let set = new Set<Subject>([chineseSubject, englishSubject])

type ElementType<T> = T extends Set<infer S> ? S : never

// 两者等价
let result1: ElementType<Set<Subject>>  //Subject类型
let result2: ElementType<typeof set>    //Subject类型

泛型和infer的区别

出现位置的不同

  • 泛型出现在函数,接口,类中
  • infer出现在 extends 后的表达式中

学习更多

TS学习地图

你可能感兴趣的:(typescript,typescript)