🤔️要求
实现类似Vue的类型支持的简化版本。
通过提供函数名称SimpleVue
(类似于Vue.extend
或defineComponent
),它应该正确地推断出计算和方法内部的this
类型。在此挑战中,我们假设SimpleVue接受带有data
,computed
和methods
字段的Object作为唯一参数,
data
是一个简单的函数,它返回一个公开上下文this
的对象,但是您无法访问data
中的数据本身或其他计算机值或方法。computed
是将上下文作为this
的函数的对象,进行一些计算并返回结果。计算结果应作为简单的返回值而不是函数显示给上下文。methods
是函数的对象,其上下文也与this
相同。方法可以访问data
,computed
以及其他methods
公开的字段。computed
与methods
的不同之处在于按原样公开的功能。
SimpleVue
的返回值类型可以是任意的。
const instance = SimpleVue({
data() {
return {
firstname: 'Type',
lastname: 'Challenges',
amount: 10,
}
},
computed: {
fullname() {
return this.firstname + ' ' + this.lastname
}
},
methods: {
hi() {
alert(this.fullname.toLowerCase())
}
}
})
📖知识点
- The
ThisType<T>
marker interface is simply an empty interface declared inlib.d.ts
. Beyond being recognized in the contextual type of an object literal, the interface acts like any empty interface.
🔗知识链接
😢问题 & 解答
🍗场景
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);