sno*_*dev 5 generics types typescript
在下面的示例代码中,TypeScript 无法推断函数中的泛型类型U,fooBar因此返回类型fooRef.doIt()为unknown。为什么会这样,我需要修改什么才能获得正确的返回类型?
interface Foo<T> {
foo(): T;
}
class Bar implements Foo<string> {
foo(): string {
return 'Bar';
}
}
class Baz implements Foo<number> {
foo(): number {
return 43;
}
}
class FooRef<T extends Foo<U>, U> {
constructor(private instance: T) {}
doIt() {
return this.instance.foo();
}
}
function fooBar<T extends Foo<U>, U>(foo: new (...args: any[]) => T) {
return new FooRef(new foo());
}
const barRef = fooBar(Bar);
barRef.doIt(); // unknown, expected string
const bazRef = fooBar(Baz);
bazRef.doIt(); // unknown, expected number
Run Code Online (Sandbox Code Playgroud)
这个答案的灵感来自@jcalz 在评论中的建议。我无法按照infer他的建议使用 使其工作,但他的建议使用ReturnType按预期工作,这就是我在这里使用的。
interface Foo<T> {
foo(): T;
}
class Bar implements Foo<string> {
foo(): string {
return 'Bar';
}
}
class Baz implements Foo<number> {
foo(): number {
return 43;
}
}
class FooRef<T extends Foo<U>, U = ReturnType<T["foo"]>> {
constructor(public instance: T) { }
doIt(): U {
return this.instance.foo();
}
}
function fooBar<T extends Foo<any>>(foo: new (...args: any[]) => T) {
return new FooRef(new foo());
}
const barRef = fooBar(Bar);
barRef.instance // (property) FooRef<Bar, string>.instance: Bar
console.log(barRef.doIt().toUpperCase()); // "BAR"
const bazRef = fooBar(Baz);
bazRef.instance // (property) FooRef<Baz, number>.instance: Baz
console.log(bazRef.doIt().toFixed(2)) // "43.00"
Run Code Online (Sandbox Code Playgroud)