首页 > 解决方案 > 打字稿类此参考未按预期工作

问题描述

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

'obj' 在其自己的类型 annotation.ts(2502) 中直接或间接引用

属性 'bazProp' 的类型在映射类型 '{ a: "a"; 中循环引用自身 fooProp: "fooProp"; barProp: "barProp"; bazProp: "bazProp"; 富:从不;酒吧:从不;baz:从不;}'.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所有类型检查。如果我取消注释该行,则会导致循环引用问题,从而导致两个 TS 错误。我怀疑这是导致线路无法工作的根本问题。athisbazPropbarProp

理想情况下,我想修复类型而不更改 TestClass 中的代码。我可以接受这bazProp不起作用。一等奖将是barProp完全按照这里定义的工作。

这是TypeScript 游乐场中的代码供您使用。

标签: typescripttypescript-generics

解决方案


推荐阅读