是否可以设置函数的通用类型而不在 Typescript 中调用它?

Ale*_*nic 7 typescript typescript-generics

问题就在标题里。下面是我想要实现的目标的示例:

const apiResponse = Promise.resolve({data: 1} as {data: any}); // Assume I don't know the type of data
const mapData = <T>(res: {data: T}): T => res.data;

const x = apiResponse.then(mapData<number>); // This one fails to compile
const y = apiResponse.then(mapData); // Succeeded but y is of type any
const z = apiResponse.then(_ => mapData<number>(_)); // Succeeded in some case it is inconvenient to forward parameters
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 4

就我个人而言,我不认为你的“详细”通话有什么问题

const z = apiResponse.then(_ => mapData<number>(_)); 
Run Code Online (Sandbox Code Playgroud)

但如果您想要其他内容,请继续阅读:


泛型函数类型,其中单个函数可以充当多种类型的函数,仅允许您在调用它时指定泛型类型参数。您的mapData函数具有以下类型:

type GenFunc = <T>(res: { data: T; }) => T
const verifyMapData: GenFunc = mapData; // okay
Run Code Online (Sandbox Code Playgroud)

请注意,这GenFunc不是泛型类型别名;它是一个特定的类型别名,引用泛型函数类型。您可以将类型参数视为T“属于”调用签名,而不是函数的名称或函数的任何类型别名的名称。因为它不属于函数的名称,所以您不能mapData<T>单独编写它,并且因为它不属于GenFunc类型名称,所以您也不能编写GenFunc<T>


将此与不同但相关的泛型类型别名进行比较,泛型类型别名引用一系列特定函数类型:

type GenAlias<T> = (res: {data: T; }) => T
Run Code Online (Sandbox Code Playgroud)

在此类型中,泛型类型参数“属于”类型别名的名称,而不属于它表示的函数类型。

不幸的是,TypeScript 的类型系统目前缺乏获取类型GenFuncGenAlias<T>自动生成类型所需的表达能力。至少现在,您需要GenAlias<T>自己手动写出 的类型定义,就像我刚才所做的那样。


编译器可以做的是认识到类型的值可以分配给您想要的任何特定GenFunc类型的变量,因此以下编译效果很好:GenAlias<T>T

const mapDataNumber: GenAlias<number> = mapData; // okay
Run Code Online (Sandbox Code Playgroud)

因此,如果重要的话,您可以编译以下内容,而无需额外的函数调用:

const w = apiResponse.then(mapDataNumber); // Promise<number>
Run Code Online (Sandbox Code Playgroud)

此外,如果您不想在变量赋值上浪费一行,您可以使用类型断言来降低类型安全性,但绝对不会产生运行时影响:

const v = apiResponse.then(mapData as GenAlias<number>); // Promise<number>
Run Code Online (Sandbox Code Playgroud)

其中任何一个都应该适合您。


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

链接到代码