泛型就是一个类型变量,用来存储类型,demo1 最后不应该解析成 demo2 吗?那 demo1 的返回值应该是 string 类型的,为什么会报错呢?
function demo1<T>(): T {
return '123' // 报错。不能将类型“string”分配给类型“T”。“T”可以使用与“string”无关的任意类型进行实例化。
}
demo1<string>()
----------
function demo2(): string {
return '123'
}
demo2()
泛型,虽然名为“泛”,但实际起到的是声明和约束的作用。
在声明一个函数的时候,如果返回值是无约束的泛型,表示它可以在使用的时候指定(或推断)为任意类型,比如题中定义的
demo1<T>(): T
,在使用时可能是这样的第一种情况,在
demo1
里返回字符串是没问题的,但是第二种情况下类型不匹配。定义函数的时候并不知道使用者会传入什么样的类型参数,所以直接把 T 当作 string 来使用是不行的。如果一个函数完全自主决定返回值,那返回类型在写这个函数的时候就已经明确了,所以不需要使用泛型,直接写成下面这样就对了
这里还有一个因素是 Runtime 没有类型,不像 C# 可以在运行时拿到类型信息。所以 TS 的类型参数并不能用于业务代码,如果是在 C# 中是可以直接拿类型来用的,比如
那么,在 TypeScript 中仅指定返回类型为泛型其实没什么应用场景,至少需要由函数参数带入这个类型信息并在内部进行计算。比如下面这个示例,在
demo2
中使用了参数 arg,再把它返回出来,这个函数的输出类型 T 和输入类型 T 一致,就可以根据传入的参数来推导