在看 vue-class-component 这个库源码的时候,注意到有这样的一个类型定义:

function Component <V extends Vue>(options: ComponentOptions<V> & ThisType<V>): 
<VC extends VueClass<V>>(target: VC) => VC

这是组件装饰器 Component 的类型定义,它接收初始化 vue 组件实例所需的选项,返回的是接收一个组件作为参数的函数,最后该函数直接返回传入的组件,意思就是,这个装饰器允许我们这样使用:

@Component({
  methods: {},
  filters: {},
})
class Demo extends Vue {
  
  method1() {}
  method2() {}

}

我们既可以给装饰器传初始化参数作为组件的 options ,也可以在组件内部定义 options ,最后都会合并到当前组件上。

不过 ThisType<V> 这个用法是我第一个见到,所以就去 Google 了一下,才知道这是 TypeScript 标准库内置的一个泛型类型。

含义

既然是标准库提供的,去 TypeScript/es5.d.ts 看了一下该类型的详细定义是这样的:

/**
 * Marker for contextual 'this' type
 */
interface ThisType<T> { }

它实际上是一个空的接口,根据官方文档的介绍,它不返回任何转换过的类型,而是作为*对象字面量*上下文 this 的标识,并且要使用这个类型,需要启用配置 -noImplicitThis

用法

总结上面的意思就是:我们可以用它来表明对象字面量中方法的 this 的类型。所以,再回到开头的定义:

function Component <V extends Vue>(options: ComponentOptions<V> & ThisType<V>): <VC extends VueClass<V>>(target: VC) => VC

这里泛型参数 V 是一个 Vue 组件, options: ComponentOptions<V> & ThisType<V> 表示 optionsthis 指向的就是 V

全局搜索了标准库文件,发现 Object 的几个静态方法也使用了这个类型:


create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;

defineProperty(o: any, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): any;

defineProperties(o: any, properties: PropertyDescriptorMap & ThisType<any>): any;

说明这几个方法并不在乎提供的 properties 或者 attributes 的 this 指向什么,因为最终都指向 o

再看官方文档中提供的例子:

// Compile with --noImplicitThis

type ObjectDescriptor<D, M> = {
    data?: D;
    methods?: M & ThisType<D & M>;  // Type of 'this' in methods is D & M
}

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
    let data: object = desc.data || {};
    let methods: object = desc.methods || {};
    return { ...data, ...methods } as D & M;
}

let obj = makeObject({
    data: { x: 0, y: 0 },
    methods: {
        moveBy(dx: number, dy: number) {
            this.x += dx;  // Strongly typed this
            this.y += dy;  // Strongly typed this
        }
    }
});

obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);

makeObject 函数的参数中 methods 类型的被定义为 M & ThisType<D & M>, 所以 methodsthis 最后指向的是 { x: number, y: number } & { moveBy(dx: number, dy: number): number }