为什么在 TypeScript 中类型别名不适用于泛型函数?
例如,这里的 TS 没有将 Identical 类型定义为泛型。
type Identical = <T>(v: T) => T;
const identical: Identical<string> = (v) => v
我知道正确的变体是:
type Identical<T> = (v: T) => T;
但是为什么第一个例子不起作用以及什么类型的
T
?
最佳答案
在下文中,我将使用“特定”一词来表示“非通用”。通常人们对此说“具体”,但我担心有人会认为这意味着“不是abstract
”,而这与abstract
无关。类。
除了泛型函数,TypeScript 只有泛型类型,没有 generic values .对于泛型类型,类型参数写在类型名称后的尖括号中:
type GenericType<T> = {x: T};
你可以有一个像
Foo<T>
这样的泛型类型。 ,但该类型的任何实际值必须是特定的,实际特定类型指定为 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;
是第一个是泛型类型,在指定时将引用特定函数,而第二个是特定类型,它引用泛型函数。尽管它们是相关的,但这些类型并不等效。您可以分配类型为
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>
是有效的 IdGenericFunc
. IdGenericType<T>
之间的关系和 IdGenericFunc
是IdGenericFunc
本质上是IdGenericType<T>
的交集所有可能的 T
:// type IdGenericFunc = forall T. IdGenericType<T>; // invalid syntax
但是没有办法直接在 TypeScript 中表达(我从 Haskell 借用了
forall
语法)。见TypeScript GitHub issue on generic values了解更多信息。好的,希望有帮助;祝你好运!
Link to code
关于typescript - 泛型函数类型别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58770087/