typescript - 调整作为函数参数传递的对象中方法的“this”上下文
问题描述
我在将this
上下文更新为作为参数传递的对象方法时遇到问题。
function decorate<T extends {
[K in keyof T]: T[K] extends (this: infer This, ...args: infer Args) => infer Return
? (this: This & { abc: 10 }, ...args: Args) => Return
: never;
}>(object: T) {
// @ts-ignore: just a hack to show a simple example
object.abc = 10;
return object;
}
decorate({
getString() { return "abc"; },
doSomething() {
const str: string = this.getString(); // Property 'getString' does not exist on type '{ abc: 10; }'.(2339)
const abc: number = this.abc;
}
});
TypeScript 检测abc
正确,但无法访问原始上下文。深入挖掘,看起来推断This
是unknown
:
function decorate<T extends {
[K in keyof T]: T[K] extends (this: infer This, ...args: infer Args) => infer Return
? (this: This, ...args: Args) => Return
: never;
}>(object: T) {
// @ts-ignore: just a hack to show a simple example
object.abc = 10;
return object;
}
decorate({
getString() { return "abc"; },
doSomething() {
const str: string = this.getString(); // Object is of type 'unknown'. (2571)
const abc: number = this.abc; // Object is of type 'unknown'. (2571)
}
});
我尝试直接将原始对象用作上下文,但T
此时仅将其检测为对象({}
),具有未知属性:
function decorate<T extends {
[K in keyof T]: T[K] extends (...args: infer Args) => infer Return
? (this: T, ...args: Args) => Return
: never;
}>(object: T) {
// @ts-ignore: just a hack to show a simple example
object.abc = 10;
return object;
}
decorate({
getString() { return "abc"; },
doSomething() {
const str: string = this.getString(); // Property 'getString' does not exist on type '{}'. (2339)
const abc: number = this.abc; // Property 'abc' does not exist on type '{}'. (2339)
}
});
有没有办法调整传递对象的方法的上下文,或者可能有完全不同的方法来达到类似的效果?
解决方案
我认为你最好的选择是使用ThisType
. 这是编译器的一个特殊标记接口,可让您轻松指定this
应表示的含义。当您将对象分配给类型为 的位置时ThisType<T>
,T
被认为是this
在该对象中定义的任何方法/函数的类型。
有了这个,您的问题的解决方案变得非常简单:
function decorate<T>(object: T & ThisType<T & { abc: number }>) {
return Object.assign( object, { abc: 10 });
}
decorate({
getString() { return "abc"; },
doSomething() {
const str: string = this.getString(); // Property 'getString' does not exist on type '{}'. (2339)
const abc: number = this.abc; // Property 'abc' does not exist on type '{}'. (2339)
}
});
推荐阅读
- design-patterns - 物理对象双缓冲
- python - Python - 如何填写网络表单然后下载生成的文件
- sql - 错误:18456,严重性:14,状态:38 原因:无法打开明确指定的数据库“ReportServer”。[客户:
] - html - HTMLElement.offsetTop 与静态父元素一起使用
- swift - 将 detailView 交换为不同的视图时,tableView 中的错误
- docker - 使用 docker-compose 为 AWS CodeBuild 创建自定义构建映像
- ruby-on-rails - Rails 中的多级数据库检索
- service - 当我已经用 Junit 测试了 Facade 时,是否有必要测试 DAO 类?
- python - 如何在 python 中解压使用 Swift 保存的二进制数据?
- javascript - 在 Reactjs 中管理状态时遇到问题