繁体   English   中英

当 function 将始终接收其定义的类型时,是否有一种方法可以表达接口 function 多态性?

[英]Is there a way to express interface function polymorphism when the function will always receive the type it's defined on?

我希望定义一个接口层次结构,其中基本接口声明 function,并且该 function 的每个扩展版本都接收其自己的类型(而不是基本类型)。 至少,我尝试过:

interface IBase {
  a: string,
  f: (x: IBase) => any // Cause of the problem
}

interface IExtension extends IBase {
  b: string,
}

const f1 = (x: IExtension) => //... typechecks when using x.b

const ext1: IExtension = {
  a: "a1",
  b: "b1",
  f: f1 // This line doesn't typecheck because IExtension is not strictly IBase
}
  

类型错误:

Type '(x: IExtension) => {}[]' is not assignable to type '(x: IBase) => any'

四处寻找,我看到了这个关于 strictFunctionTypes 的答案 进行以下更改会导致程序进行类型检查,因为方法不受strictFunctionTypes的约束,因此允许双变:

interface IBase {
  a: string,
  f(x: IBase): any
}

编辑:正如@jcalz评论中所解释的那样,这种方法显然是不合理的。 它也没有捕获f以其定义的类型调用的约束。

有没有办法在 TypeScript 中表达这种输入? 就像是:

interface IBase {
  a: string,
  f: (x: IBase | * extends IBase) => any
}

我一直无法找到类似的东西来避免 generics。我知道 generics 可以在这里使用,但我不会走那条路,特别是考虑到方法语法按预期工作。 非常感谢关于此主题的任何其他见解!

看起来您想使用多态this type ,这是一种引用当前类型的隐式泛型类型:

interface IBase {
  a: string,
  f: (x: this) => any
  //     ^^^^
}

然后,当您扩展IBase时,扩展的f方法将自动引用扩展而不是IBase

interface IExtension extends IBase {
  b: string,
}

type IXF = IExtension['f'];
// type IXF = (x: IExtension) => any

const ext1: IExtension = {
  a: "a1",
  b: "b1",
  f: x => x.b.toUpperCase()
}

interface ISomethingElse extends IBase {
  z: number
}

type ISF = ISomethingElse['f']
// type ISF = (x: ISomethingElse) => any

const sth2: ISomethingElse = {
  a: "a2",
  f: s => s.z.toFixed(),
  z: 123
}

游乐场代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM