关键字
一、in
二、is
is
被称为类型谓词,用来判断一个变量属于某个接口或类型。如果需要封装一个类型判断函数,你应该第一时间想到它。is
关键字一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型。
2.1 语法
prop is type
2.2 场景
场景一、Vue3
中 Ref
类型判断
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
中的只读修饰符,可以声明更加严谨的可读属性。通常在 interface
、 Class
、 type
以及 array
和 tuple
类型中使用它,也可以用来定义一个函数的参数
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
修饰的属性能确保自身不能修改属性,但是当你把这个属性交给其它并没有这种保证的使用者(允许出于类型兼容性的原因),他们能改变