当前位置: 首页 > 知识库问答 >
问题:

具有泛型返回类型的Typescript函数

贺宜修
2023-03-14
type FuncGenericReturn = <T>() => T;
const funcReturnsNumber: FuncGenericReturn = (): number => 1;

(沙盒)

获取此错误:

类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。

我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢

共有2个答案

阮昊阳
2023-03-14

这种语法不适合你吗?

type FuncGenericReturn<T> = () => T;
const funcReturnsNumber: FuncGenericReturn<number> = () => 1;

万坚壁
2023-03-14

重要的是要注意泛型类型参数在哪里声明以及它们的作用域。类型

type FuncGenericReturn = <T>() => T;

是指泛型函数的具体类型<代码>

declare const funcGenericReturn: FuncGenericReturn;

那么你应该可以这样称呼它:

const someNumber: number = funcGenericReturn<number>(); 
const someString: string = funcGenericReturn<string>();

但是当然在运行时,它们都将编译为

const someNumber = funcGenericReturn();
const someString = funcGenericReturn();

这意味着funcGenericReturn()只需在运行时“知道”它应该首先返回一个数字,然后返回一个字符串,基于生成JavaScript之前删除的类型信息。因此,正确实现FuncGenericReturn需要神奇的先见之明。

重申:当您有一个泛型函数时,泛型类型参数由调用方指定,而不是由实现者指定。的确,有时编译器会推断这些类型参数,这样编写代码的人就不必把它拼出来,但同样,这些推断是在调用时发生的。对同一泛型函数的两个不同调用可能最终会有两个不同的类型参数选择。

让我们将其与不同但相关的类型定义进行比较:

type FuncConcreteReturn<T> = () => T;

这里,FuncConcreteReturn是指具体函数的泛型类型。更准确地说,funccretereturn实际上不是一种类型;它更像是一个类型运算符,它接受输入类型T,并生成输出类型=

对于任何特定类型T,类型FuncConcreteBack

const funcReturnsNumber: FuncConcreteReturn<number> = () => 1;
const funcReturnsString: FuncConcreteReturn<string> = () => "";

同样,funcReturnsNumber不是泛型函数。它是一个始终返回数字的具体函数。和返回

顺便说一句,泛型函数类型之间的关系

type G = <T, U>(t: T, u: U) => [T, U]

和泛型类型,如

type H<T, U> = (t: T, u: U) => [T, U]

前者的任何实例都将是后者的实例,但反之亦然。这意味着,如果您确实有一个FuncGenericReturn,则可以将其分配给类型为FuncConcreteReturn的值

const fn: FuncConcreteReturn<number> = funcGenericReturn; // okay
const fs: FuncConcreteReturn<string> = funcGenericReturn; // okay

或者,对于上面的G和H类型,您可以这样做:

const g: G = <T, U>(t: T, u: U) => [t, u];
g("a", 1); // okay
g(1, "a"); // okay

const h1: H<string, number> = g; // okay
h1("a", 1); // okay
h1(1, "a"); // error

const h2: H<number, string> = g; // okay
h2(1, "a"); // okay
h2("a", 1); // error

好的,我希望这能让你们理解泛型函数和泛型类型之间的区别。祝你好运

游乐场链接到代码

 类似资料:
  • 我想通过TypeScript泛型定义函数返回类型。所以R可以是我将定义的任何东西。 <代码>。。。许诺 错误:(29,9)TS2322:类型“字符串”不可分配给类型“R”。“字符串”可分配给类型“R”的约束,但“R”可以用约束“{}”的不同子类型实例化。

  • 我试图在静态编程语言中创建一个非常简单的泛型NDArray类,它将lambda表达式作为初始化函数。 典型的用法是: 我的问题是Kotlin编译器抱怨构造函数中值的初始化 通过说“不能使用‘T’作为具体化类型参数。改用类”。为什么? 编辑: 如果我用我自己的MyArray替换静态编程语言Array实现,它会编译: 不确定为什么静态编程语言对待MyArray与常规数组不同,当两者具有相同的构造函数时

  • 问题内容: 对于一个抽象类,我想定义一个为子类返回“ this”的方法: 我希望能够执行以下操作: 可以说香蕉面包会抛出一个IllegalArgumentException消息“不是蛋糕!”。 问题答案: 编辑 要求子类以某种方式表现是没有问题的,这超出了静态类型可以检查的范围。我们一直在这样做-一页又一页的普通英语指定您如何编写子类。 提出的另一种具有协变返回类型的解决方案必须做同样的事情-用简

  • 我有一个问题,从抽象类中重写泛型方法。 这是我的抽象类: 当我创建类(B)来实现类(a)时,如下所示: 显示了(getData)方法中的以下编译错误: ”“B。getData“(“字符串函数(字符串)”不是“a”的有效重写。getData'('字符串函数(类型)‘)。dart(无效覆盖) 以及返回语句中的此错误: 类型为“String”的值不能从方法'getData'返回,因为它的返回类型为'St

  • 如何为动态创建的函数声明泛型类型? 我如何在中使用并传递? < code>useFoo的预期用法

  • 我正在尝试返回一个对象,它应该是IClass的一个实现,具有一个通用类型,是IType的一个实现。 我要返回的实际类扩展了Class (abstract ),其泛型类型为ActualType: 抽象类对象实现了IClass接口,可以有任何扩展IType的类型 ActualType只是实现了IType接口 我在编译时得到一个“类型不匹配:无法从ActualClass转换为IClass”错误。我不明白