有这样的例子:
interface A {
method: (itself: this) => string;
}
interface B extends A {
additionalProperty: boolean;
}
type Extend<T extends A> = A & { extension: number };
type ExtendedA = Extend<A>
type ExtendedB = Extend<B>
.
当我尝试延长B
打字稿写道:
类型“B”不满足约束“A”。
属性“方法”的类型不兼容。
类型“(itself: B) => string”不可分配给类型“(itself: A) => string”。
参数“itself”和“itself”的类型不兼容。
类型“A”中缺少属性“additionalProperty”,但类型“B”中需要属性“additionalProperty”。(2344)
input.tsx(6, 2): 此处声明了“additionalProperty”。
But B
延伸A
。它们应该是兼容的。
更新#1:
我无法解释这一点,但是看来如果我用类替换接口 https://www.typescriptlang.org/play?ts=4.6.2#code/MYGwhgzhAECC0G8BQBIAtgUwC4AsD2AJgBQCWWEGIAZgFzS4kQCUiqKATtgK7sB20AciwYIWAQG5UAXyQzQkGACFoGAB7DeBGPGQowBAmRJ5eYEAAV2eAA4Z2WAJ7QAvPXZcMkmUke3oAUXUMTQAeABUVIM1tAD4XaAiAMkRIjQhjXjpeLjQAIztoKUkfBz9AjQIMAnhXcuCCENgYpBKyqMqCZVr2kMUYoA打字效果完美。
更新#2:
嗯,它只适用于类方法,但不适用于例如箭头函数。还是很奇怪。
更新#3
如果接口按以下方式定义,则它将不起作用:
interface A {
method: (itself: this) => string;
}
但如果它按以下方式定义,它就可以工作:
interface A {
method(itself: this): string;
}
它根本没有任何意义。但寻找这种行为的原因我发现这个优秀的答案 https://stackoverflow.com/a/70277549。它让我了解了这种差异的原因。
有人提到了 TypeScript 选项strictFunctionTypes https://github.com/microsoft/TypeScript-Website/blob/v2/packages//tsconfig-reference/copy/en/options/strictFunctionTypes.md.
启用后,此标志会导致更正确地检查函数参数。
在开发此功能的过程中,我们发现了大量本质上不安全的类层次结构,包括 DOM 中的一些。因此,该设置仅适用于以函数语法编写的函数,不适用于以方法语法编写的函数
它解释了这种奇怪的行为差异的原因。我可以关闭这个选项,但这感觉像是一个解决方法。
我还需要另一个解决方案。
更新#4
我认为此错误是为了防止此类不安全的分配而指定的:
const a: A = {
method(b: B) {
return `${b.toString()} / ${b.additionalProperty}`;
}
}
但此类错误并不特定于我的情况。
更新#5
我找到了另一个解决方法
type Method<T extends (...args: any) => any> = {
f(...args: Parameters<T>): ReturnType<T>;
}['f'];
interface A {
method: Method<(itself: this) => string>;
}
interface B extends A {
additionalProperty: boolean;
}
type Extend<T extends A> = T & { extension: number };
type ExtendedA = Extend<A>
type ExtendedB = Extend<B>
自己检查一下 https://www.typescriptlang.org/play?ts=4.6.2#code/C4TwDgpgBAshwAsD2ATAPAFShAHsCAdigM5QAUAdFQIYBOA5sQFxTUEgCUUAvAHyvt+3KAG8AUAEgAZpRoNmUAAp1qAW3gRaxTLw4sASvACutAhnAQdAbjEBfANoByKY4C6NsQEsC+WlOoAxtAAgqKS6oioLHCR6GSewMQQADZSLIiexFx8UMTAtN70vDa2Yl4+mv5BUABC2HiEJFCh4hLUKCgJnkgE1MmKtEiQtKAsAEZISMkQbCVloJBQAKINRJj1+ESkwUJQWABkohuExN0ELARGqmOaULYeC9ArmygQKKHCz41oO-MWy6tXig6p9AWgarwgA。这比禁用更好strictFunctionTypes
,但这仍然是解决方法。