通用函数类型别名

时间:2019-11-08 16:06:47

标签: typescript

为什么在TypeScript类型别名中,泛型函数不起作用? 例如,在这里TS并未将Identical类型定义为泛型。

type Identical = <T>(v: T) => T;

const identical: Identical<string> = (v) => v

我知道正确的变体是:

type Identical<T> = (v: T) => T;

但是为什么第一个示例不起作用,以及哪种类型的T

1 个答案:

答案 0 :(得分:2)

在下文中,我将使用“特定”一词来表示“非通用”。通常人们对此表示“具体”,但我担心有人会认为这意味着“不是abstract”,这与abstract类无关。


除通用函数以外,TypeScript仅具有通用 types ,而没有generic values。对于泛型类型,类型参数写在类型名称后的尖括号中:

type GenericType<T> = {x: T};

您可以使用Foo<T>之类的通用类型,但是该类型的任何实际 value 必须是特定的,并且将特定的实际特定类型指定为T

declare const badValue1: GenericType; // error, requires 1 type argument
declare const badValue2: GenericType<T>; // error, cannot find name 'T'
declare const goodValue: GenericType<string>; // okay

请注意,GenericType<string>现在是特定于类型,等效于{x: string}。因此,一旦通过插入特定类型在通用类型中指定通用参数,就可以得到特定类型。


通用函数是不同的:通用函数类型的值是通用的。它充当不同特定功能类型的完整系列。对于通用函数类型,将类型参数写在函数参数列表之前的尖括号中:

type GenericFunction = <T>(x: T, y: T) => void;

泛型函数的类型本身不一定是泛型的。上方GenericFunction名称上没有类型参数。因此,您不能通过添加来指定通用类型参数。只有在调用函数时,才能指定通用函数类型参数:

declare const badFunc: GenericFunction<string>; // error, GenericFunction is not generic
declare const goodFunc: GenericFunction; // okay
const ret = goodFunc<string>("okay", "fine"); // okay, type parameter specified as string
const ret2 = goodFunc("okay", "fine"); // also okay, type parameter inferred as string

因此,它们之间的区别:

 type IdGenericType<T> = (x: T) => T;
 type IdGenericFunc = <T>(x: T) => T;

是第一个是 generic 类型,在指定时将引用 specific 函数,而第二个是 specific 类型,是指 generic 函数。尽管这些类型是相关的,但它们并不等效。您可以为所需的任何特定类型IdGenericFunc的类型IdGenericType<XXX>的任何变量分配类型XXX的值:

let id: IdGenericFunc = x => x;
let idString: IdGenericType<string> = id; // okay

反之亦然:

const otherId: IdGenericFunc = idString; // error! T not assignable to string

这很有意义,因为仅知道IdGenericType<string>会接受并输出string

idString = x => x + "!"; // okay

因此,您不能假设IdGenericType<string>是有效的IdGenericFuncIdGenericType<T>IdGenericFunc之间的关系是,对于所有可能的IdGenericFuncIdGenericType<T>本质上是T 交集。 / em>:

// type IdGenericFunc = forall T. IdGenericType<T>; // invalid syntax

但是无法直接在TypeScript中表达它(我从Haskell借用了forall语法)。


有关更多信息,请参见TypeScript GitHub issue on generic values。好的,希望能有所帮助;祝你好运!

Link to code