跳到主要内容

关键字

一、in


二、is


is 被称为类型谓词,用来判断一个变量属于某个接口或类型。如果需要封装一个类型判断函数,你应该第一时间想到它。is 关键字一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型。

2.1 语法

prop is type

2.2 场景

场景一、Vue3Ref 类型判断

export interface Ref<T = any> {
value: T;
}

export function isRef(r: any): r is Ref {
return !!(r && r.__v_isRef === true);
}

三、this


TypeScript 中的 this 和 JavaScript 中的 this 有什么差异呢?

四、infer


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

4.1 语法

infer 用于 extends 条件语句后的泛型具体化类型上

type Person<T> = {
name: T,
age: number
}
type InferResultType<T> = T extends Person<infer P> ? P : T;

const x: string = '呵呵';
let person: InferResultType<typeof x>;

infer 用于 extends 条件语句后的函数类型的返回值类型上

type PersonType = {
name: string;
age: number;
}
type PersonFuncType = (person: PersonType) => string;
type InferType<T> = T extends (params: any) => infer P ? P : T;
type InferResultType = InferType<PersonFuncType>;

infer 用于 extends 条件语句后的函数类型的参数类型位置上

type PersonType = {
name:string;
age:number;
}
type PersonFuncType = (person:PersonType) => string;
type InferType<T> = T extends (params:infer P)=>any?P:T;
type InferResultType = InferType<PersonFuncType>;

4.2 场景

  • 场景一、构造函数参数类型注解-通过 infer P 获取构造函数参数

    class Person {
    public name: string;
    public age: number;
    constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    }
    }

    type ConstructorType = new (...args: any[]) => any;
    type ConstructorTypeT<T> = new (...args: any[]) => T;
    type ConstructorParamsType<T extends ConstructorType> = T extends new (...args: infer P) => any ? P : any;

    function createInstance<T>(constructor: ConstructorTypeT<Person>, ...args: ConstructorParamsType<typeof Person>) {
    return new constructor(...args)
    }

    const person = createInstance<Person>(Person,'柏拉图',23)

4.3 infer 与 泛型的区别?

五、keyof


keyof 获取某种类型的所有键,其返回类型是联合类型。

5.1 语法

语法一、keyof any 时,Typescript 规定结果为 string | number | symbol

type Type = keyof any; // 结果: string | number | symbol

语法二、keyof 用于对象类型时,返回属性名

interface Person {
name: string;
age: number;
location: string;
}

type K1 = keyof Person; // "name" | "age" | "location"

语法三、keyof 用于数组类型时,返回数组自身属性名

interface Person {
name: string;
age: number;
location: string;
}

type K2 = keyof Person[]; // number | "length" | "push" | "concat" | ...

5.2 场景

场景一、设置对象 key 类型

const object = {
name:"哈哈",
age:23
}
type ObjectKeyType = keyof typeof object;
const bar:ObjectKeyType = "name"

六、typeof


6.1 场景

场景一、设置对象 key 类型

const object = {
name:"哈哈",
age:23
}
type ObjectKeyType = keyof typeof object;
const bar:ObjectKeyType = "name"

场景二、用于特定的构造函数类型注解: typeof 具体类 === new (具体类构造函数参数) => 具体类

class Person {
public name: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}

let p1Constructor: new (name:string,age:number) => Person = Person
let p2Constructor: typeof Person = Person

// 说明: new (name:string,age:number) => Person 与 typeof Person 作用效果相同

七、readonly


readonly: TypeScript 中的只读修饰符,可以声明更加严谨的可读属性。通常在 interfaceClasstype 以及 arraytuple 类型中使用它,也可以用来定义一个函数的参数

readonly 修饰字面量数组

let array:readonly number[] = [10,20,30];
array[0] = 40; // 报错

readonly 用于修饰字面量元组

let array:readonly [number,number] = [10,20];
array[0] = 40; // 报错

readonly 用于修饰对象类型属性

type Person = {
readonly name: string;
age:number;
}

readonly 用于修饰函数的参数

function foo(params:{readonly name:string}){
console.log(params);
}

foo({name:'哈哈哈'})

7.1 readonly vs const ?

  • const 用于声明变量,一旦赋值,值不可以更改。对于数组、对象而言,通过const声明后,还是可以改变其属性或者元素值得。

  • readonly 用于修饰数组、元组、以及对象类型属性,使其不可更改,通过readonly修饰的数组,元素值也不被更改。但是: readonly 修饰的属性能确保自身不能修改属性,但是当你把这个属性交给其它并没有这种保证的使用者(允许出于类型兼容性的原因),他们能改变

参考资料


TypeScript is 关键字