“ThisType”不会影响包装器内方法中的“this”

`ThisType` does not affect the `this` in the method inside a wrapper

提问人:Lomírus 提问时间:7/20/2023 更新时间:7/20/2023 访问量:48

问:

我想在下面的代码中访问,编译器可以按预期推断出 as number 的类型。this.data.athis.data.a

function defineComponent<T, U>(
  options: {
    data: T;
    methods: U;
  } & ThisType<{ data: T }>
): void {}

defineComponent({
  data: {
    a: 1,
  },
  methods: {
    fn() {
      console.log(this.data.a)
    },
  },
});

但是,当我想包装 with 时,我无法访问 this,因为编译器告诉我fn()throttle()'this' implicitly has type 'any' because it does not have a type annotation.

function defineComponent<T, U>(
  options: {
    data: T;
    methods: U;
  } & ThisType<{ data: T }>
): void {}

function throttle<T extends Function>(fn: T, time: number) {
  return fn;
}

defineComponent({
  data: {
    a: 1,
  },
  methods: {
    fn: throttle(function () {
      console.log(this.data.a)
    }, 1000),
  },
});

那么我怎样才能让编译器将这个类型推断为 for?在 Kotlin 中,我可以用来指定要使用的,但在 TS 中不受支持。也许我可以写成 ,但是编写编译器应该为开发人员完成的函数太多余了。我也试过了,但是,它也无法推断出 的类型。fn()ThisType optionsthis@xxxthisthorottle(function(this: { data: a }) { /* ... */}, 1000)throttle<typeof this>()this

TypeScript 限制

评论

0赞 jcalz 7/20/2023
TS 的上下文类型很脆弱(例如,请参阅此 q);这是一个设计限制。 在对象内部添加上下文类型,但它不会进入该对象内部的函数调用。在这种情况下,即使编译器“应该”已经这样做了,你也必须进行注释(说它“应该”做某事很容易,但实现编译器来做它“应该”做的所有事情要困难得多)。如图所示。这是否完全解决了这个问题?如果是这样,我会写一个答案;如果没有,我错过了什么?ThisType<T>this
0赞 Lomírus 7/24/2023
@jcalz 对于,我必须注释类型,但是当有很多方法或数据时很麻烦,所以它不能满足我的要求。对于 ,返回一个函数,并且返回的函数是立即调用的,因此 应该返回 (返回的类型 ),这意味着它也不起作用。fn2fn3throttle()fn3voidfn
0赞 jcalz 7/24/2023
我知道它不符合您的要求;我是说无法满足您的要求,因为 TS 不会按照您想要的方式传播上下文类型。这是语言的设计限制。所以,忽略(这在语义上与你想要的版本并不相同),类似的事情是你能做的最好的事情。这是否完全解决了这个问题(即,“我怎样才能做到X”,“你不能,因为Y”),或者我是否遗漏了你正在寻找的东西?fn3fn2
0赞 Lomírus 7/25/2023
@jcalz 感谢您的回答,但遗憾的是它并没有解决我的问题。因为我之所以写这个函数,就是为了减少类型定义。目前我的解决方案是这样的:在 的内部实现中添加一个方法,并在创建组件时调用它以重新分配defineComponent({ methods: { fn() { /* ... */ }}, lifetimes: { created() {this.fn = throttle(this.fn, 1000 )} } });created()defineComponentfnthrottle(fn)

答: 暂无答案