TypeScript:使通用接口 A<T> 的方法仅在 T 是某种类型时可用
TypeScript: make a method of a generic interface A<T> available only if T is of a certain type
请看这段代码:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2();
我希望 foo
与 B<Function>
类型兼容,但我却得到 error TS2339: Property 'method2' does not exist on type 'A<Function>'
。我可以重写接口 B
以使其正常工作吗?
实际上,我正在尝试修复 lodash 的 _.memoize
:
的类型
// This should be OK. The type of result1 should be compatible with aFunction.
var result1 = _(aFunction).memoize().value();
// And this should be an error.
var result2 = _(aNonFunctionValue).memoize().value();
UPDATE. 基本上,我的问题是:我可以为 A<T>
编写这样一个通用方法,只有在 T
是其他类型的子类型 U
?
Can I rewrite the interface B somehow to get it to work?
解决方案
代码如下:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
interface A<T> {
method2<T extends Function>(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2(); // works!
找到解决方案
让我们退后一步,想想我们想要做什么:
var foo: A<Function>;
foo.method2(); // Should work
这意味着 A<Function>
上应该有 method2
。所以:
interface A<T> {
method2<T extends Function>(): B<T>;
}
并且此方法二在 T
和 returns 类型 B
上添加了通用约束。
剩下的在最终的解决方案中就清楚了
原来 TypeScript 不支持这个。参见 https://github.com/Microsoft/TypeScript/issues/1290
2019 年更新: 现在我们有 Conditional Types,这是小菜一碟:
interface A<T> {
method1(): A<T>;
method2: T extends Function ? () => A<T> : never;
}
declare var foo: A<Function>;
foo.method1();
foo.method2();
请看这段代码:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2();
我希望 foo
与 B<Function>
类型兼容,但我却得到 error TS2339: Property 'method2' does not exist on type 'A<Function>'
。我可以重写接口 B
以使其正常工作吗?
实际上,我正在尝试修复 lodash 的 _.memoize
:
// This should be OK. The type of result1 should be compatible with aFunction.
var result1 = _(aFunction).memoize().value();
// And this should be an error.
var result2 = _(aNonFunctionValue).memoize().value();
UPDATE. 基本上,我的问题是:我可以为 A<T>
编写这样一个通用方法,只有在 T
是其他类型的子类型 U
?
Can I rewrite the interface B somehow to get it to work?
解决方案
代码如下:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
interface A<T> {
method2<T extends Function>(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2(); // works!
找到解决方案
让我们退后一步,想想我们想要做什么:
var foo: A<Function>;
foo.method2(); // Should work
这意味着 A<Function>
上应该有 method2
。所以:
interface A<T> {
method2<T extends Function>(): B<T>;
}
并且此方法二在 T
和 returns 类型 B
上添加了通用约束。
剩下的在最终的解决方案中就清楚了
原来 TypeScript 不支持这个。参见 https://github.com/Microsoft/TypeScript/issues/1290
2019 年更新: 现在我们有 Conditional Types,这是小菜一碟:
interface A<T> {
method1(): A<T>;
method2: T extends Function ? () => A<T> : never;
}
declare var foo: A<Function>;
foo.method1();
foo.method2();