在Typescript中,如何在工厂(ish)函数中实例化的类上获取方法的通用返回类型
Posted
技术标签:
【中文标题】在Typescript中,如何在工厂(ish)函数中实例化的类上获取方法的通用返回类型【英文标题】:In Typescript how to get the generic return type of a method on a class instantiated in a factory(ish) function 【发布时间】:2021-10-11 14:48:21 【问题描述】:在下面的示例代码中,TypeScript 无法在fooBar
函数中推断出泛型类型U
,因此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
【问题讨论】:
我很难想出一个准确描述我的问题的标题。如果您有更好的建议,请告诉我。 鉴于此示例代码,我将删除您的T
,仅使用U
,如this。如果由于某种原因您需要T
,我会删除U
并像this 一样重写它(并使用ReturnType<T["foo"]>
或T extends Foo<infer U> ? U : never
之类的东西从T
计算U
)。如果其中任何一个对您有用,我将很乐意写下答案。让我知道您想在这里看到哪些(如果有的话)。如果两者都没有,请详细说明缺少的内容。
@jcalz 太棒了!我确实需要知道扩展 Foo 的具体类的类型(我应该将 instance
公开),所以你的第二个选项应该可以工作。如果您继续写一个答案,显示使用ReturnType
和infer
的示例,那就太好了。
【参考方案1】:
这个答案的灵感来自@jcalz 在 cmets 中的建议。正如他所建议的那样,我无法使用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"
【讨论】:
以上是关于在Typescript中,如何在工厂(ish)函数中实例化的类上获取方法的通用返回类型的主要内容,如果未能解决你的问题,请参考以下文章