打字稿类此参考未按预期工作

时间:2021-04-07 07:53:19

标签: typescript typescript-generics

我使用一些 TypeScript 实用程序类型对函数定义进行了改进,以便它从定义中排除函数属性,这对我的用例至关重要。 一旦我包含了这个映射类型,我就开始出现一些奇怪的 TS 行为,包括这些错误:

<块引用>

'obj' 在它自己的类型注解中被直接或间接引用。ts(2502)

<块引用>

'bazProp' 属性的类型在映射类型 '{ a: "a"; 中循环引用自身。 fooProp: "fooProp"; barProp: "barProp"; bazProp: "bazProp";富:从不;酒吧:从不;巴兹:从不; }'.ts(2615)

下面是我的新旧版本函数的代码。

注意:请不要看这段代码的功能方面,因为这是一个演示问题的虚构示例。

type AnyFunction = (...args: any[]) => any;
type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends AnyFunction ? never : K;
}[keyof T];
type PropsOnly<T> = Pick<T, NonFunctionPropertyNames<T>>;

function calcValueOld<T, TReturn>(thisRef: T, getter: (obj: T) => TReturn): TReturn {
  return getter(thisRef);
}

function calcValueNew<T, TReturn>(thisRef: T, getter: (obj: PropsOnly<T>) => TReturn): TReturn {
  return getter(thisRef);
}

class TestClass {
  a = 123;
  fooProp = calcValueOld(this, (obj) => obj.a * 2);
  barProp = calcValueNew(this, (obj) => obj.a * 2);
  // Uncomment the following line to see the circular reference issue
  // bazProp = calcValueNew<TestClass, number>(this, (obj) => obj.a * 2);

  foo(): number {
    return calcValueOld(this, (obj) => obj.a * 2);
  }
  bar(): number {
    return calcValueNew(this, (obj) => obj.a * 2);
  }
  baz(): number {
    return calcValueNew<TestClass, number>(this, (obj) => obj.a * 2);
  }
}

barProp 调用已丢失对 a 类型的 this 属性的所有类型检查。 如果我取消注释 bazProp 行,则会导致循环引用问题,从而导致两个 TS 错误。我怀疑这是导致 barProp 行不起作用的根本问题。

理想情况下,我希望在不更改 TestClass 代码的情况下修复类型。我可以接受 bazProp 不起作用。一等奖是 barProp 完全按照此处定义的方式工作。

这是 TypeScript playground 中的代码供您使用。

0 个答案:

没有答案