ThisType
是ts中内置了一种类型,查看源码发现只能知道它的作用,定义方法中啥都没有
/**
* Marker for contextual 'this' type
*/
interface ThisType<T> { }
下面说明一下它怎么用,啥时候用
ThisType
ThisType
和this
参数都是指定函数的运行时this
指向的类型,它们的使用不同
this
参数是作为函数的参数定义的,它可以定义在任何函数上ThisType
定义一个对象中的所有函数的this
指向类型,它只能在对象的类型声明时使用
initEnvPropertiesB
调用了自己的initABC
方法给自己添加了三个符合Env
规范的属性
abstract class Env {
a!: number;
b!: string;
c!: boolean;
}
interface InitEnvPropertiesB {
e: string;
initABC: () => void;
}
const initEnvPropertiesB: InitEnvPropertiesB & ThisType<Env> = {
e: "e",
initABC() {
this.a = 2;
this.b = "B";
this.c = false;
// this.e = "E"; // error this中没有e属性
},
};
initEnvPropertiesB.initABC();
console.log(initEnvPropertiesB); // 有abce四个属性
实际使用
这个类型在高级函数的封装中非常有用,如下是对Pinia
的模仿,它通过使用ThisType
提供了非常友好的代码提示,这也是typeChallenges
中的一题,←详细题目见左边链接,推荐先思考下题目再来看下面的答案
type GetterFunc = Record<string, () => any>;
type ReturnTypes<T extends GetterFunc> = {
[K in keyof T]: ReturnType<T[K]>;
};
declare function defineStore<State, Getters extends GetterFunc, Actions>(store: {
id: string;
state: () => State;
getters?: Getters & ThisType<Readonly<State> & ReturnTypes<Getters>>;
actions?: Actions & ThisType<State & Actions>;
}): State & Readonly<ReturnTypes<Getters> & Actions>;
const store = defineStore({
id: "",
state: () => ({
num: 0,
str: "",
}),
getters: {
stringifiedNum() {
// @ts-expect-error
this.num += 1;
return this.num.toString();
},
parsedNum() {
return parseInt(this.stringifiedNum);
},
},
actions: {
init() {
this.reset();
this.increment();
},
increment(step = 1) {
this.num += step;
},
reset() {
this.num = 0;
// @ts-expect-error
this.parsedNum = 0;
return true;
},
setNum(value: number) {
this.num = value;
},
},
});