[英]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.