首页 > 解决方案 > 打字稿方法中如何推断通用返回值?

问题描述

我想更好地理解 typescript 如何用泛型推断返回类型。如果一个使用泛型类型作为返回值的方法在没有泛型类型参数的情况下被调用,那么 typescript 是如何推断返回类型的?我知道泛型参数可以很容易地通过发送的类型推断出来,但如果没有提供泛型类型参数,则无法推断返回参数。

// Call: 
this.getSomething(value);

// Method signature:
getSomething<T>(inParameter: string): T { 
    ...
}

标签: typescripttypescript-generics

解决方案


让我们考虑一下getSomething()方法:

getSomething<T>(inParameter: string): T {
  return null!; // <-- this isn't safe, whatever you put here
}

你没有在那里展示实现,所以我不确定它认为它在做什么。但是签名本身是可疑的......getSomething()声称它可以T 为调用者选择的任何类型(或编译器为调用者推断)返回一个类型值,只需一个string输入。这不太可能是真的,或者至少不能轻易地被验证为类型安全。

我的意思是,没有什么能阻止我写作this.getSomething<string>("abc"),然后this.getSomething<number>("abc")。但是由于类型系统在将 TypeScript 编译为 JavaScript 时被删除this.getSomething("abc"),所以这两个调用都将作为. 可能这两个调用的结果相同,并且由于该结果不可能同时是 astring a number,因此这些 TypeScript 调用中至少有一个是错误的。


但是,让我们继续讨论您的问题:

如果您只是调用this.getSomething(value),推理可能会失败,并且T会变成{}unknown取决于您使用的 TypeScript 版本

const hmm = this.getSomething("value"); // const hmm: unknown
// inference fails, T inferred as unknown

如果您调用const t: string = this.getSomething(value)它将使用上下文类型t决定T必须是string

const t: string = this.getSomething("value");
// contextual typing, T is inferred as string

但是,如果调用者提供了一个类型的参数T或其他可能本身可能产生一个类型的值的东西,那么这对安全和推理都更好T。例如:

getSomethingReasonable<T>(inParameter: string, tArray: T[]): T {
  return tArray[inParameter.length];
}

const okay = this.getSomethingReasonable("value", [1,2,3,4,5,6,7,8]);   
// inference on tArray, T is number

它更安全,因为输入tArray提供了一种运行时机制,T即使在类型擦除的情况下也可以生成类型值。而且,正如您所指出的,这是推断T.


好的,希望有帮助。祝你好运!

链接到代码


推荐阅读