【问题标题】:Properly type dynamic functions in a proxy using TypeScript使用 TypeScript 在代理中正确键入动态函数
【发布时间】:2018-07-23 03:47:11
【问题描述】:

我有一个返回代理的函数,它使用get 陷阱从多个对象推断函数。现在我需要能够键入这些函数,因为它们在编译时在技术上是已知的,但 TypeScript 就是无法弄清楚它们。如何让 TypeScript 识别这些函数以便能够将它们添加到我的界面中?

interface IObject {
  (): IFunction;
  addAMethod(name: string, fn: (...args: any[]) => any): void;
}

interface IFunction {
  list: string[];
  option: boolean;
}

const mainFunc: IObject = Object.assign(
  (): IFunction => {
    const context = {
      list: [],
      option: true,
    };

    return new Proxy(context, handler);
  },
  {
    addAMethod(name: string, fn: (...args: any[]) => any) {
      Object.assign(core, fn);
    },
  },
);

const handler = {
  get(context: {[key: string]: any}, prop: string, receiver: IFunction) {
    if (prop in context) {
      return context[prop];
    }
    if (prop in core) {
      return core[prop];
    }
  },
};

const core = {
  evaluate: (val: any) => true,
  doSomething: (val: any) => false
}

export default mainFunc;

现在这将允许以下操作:

import mainFunc from "./mainFunc"

mainFunc().evaluate('wow'); // Should return true

这当然不会返回真,而是表明evaluate() 不是IFunction 类型的一部分,这是真的。但是当我尝试添加它时,我得到另一个错误,我无法将函数分配给IFunction,因为它没有定义evaluate()

// ...

interface IFunction {
  list: string[];
  option: boolean;
  evaluate(val: any): boolean;
}

const mainFunc: IObject = Object.assign(
  (): IFunction => {
    const context = {
      list: [],
      option: true,
    };

    return new Proxy(context, handler); // Error happens here
  },
  // ...
);

// ...

const core = {
  evaluate: (val: any) => true,
  doSomething: (val: any) => false
}

输入'{列表:从不[];选项:布尔值; }' 不可分配给类型 'IFunction'。 '{ list: never[]; 类型中缺少属性 'evaluate'选项:布尔值; }'。

知道如何输入evaluate()吗?

【问题讨论】:

  • 只是想了解addAMethod的用法应该没有额外的name参数来命名正在添加的函数吗?
  • @TitianCernicova-Dragomir 你说得对,我已经修改了。

标签: javascript typescript


【解决方案1】:

问题在于 Proxy 构造函数 assumes that the proxy will be the same type as the target parameter 的 TypeScript 类型,尽管这并不总是正确的。有一个open issue 寻求社区帮助以提供更好的打字。

如果没有这个,我认为处理这个问题的唯一方法是明智地使用类型断言和any 类型。例如,您可以将出现错误的行更改为:

return new Proxy(context, handler) as IFunction;

这可能会使错误消失。它不是完全类型安全的,但只要您确定自己在做什么,就应该没问题。而且您应该也可以将evaluate() 方法添加到IFunction 接口。

希望有所帮助;祝你好运!

【讨论】:

  • 这条评论值得一读,它建议添加一个包装函数,该函数可以使用交集类型指定返回值的正确类型。这样,函数本身可以包含其类型 unsafety(?)。 github.com/Microsoft/TypeScript/issues/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 2021-07-28
  • 2019-05-30
  • 2019-09-21
  • 1970-01-01
  • 2019-09-02
  • 2018-10-24
相关资源
最近更新 更多