介绍
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
泛型之Hello World
下面来创建第一个使用泛型的例子:identity函数。 这个函数会返回任何传入它的值。 你可以把这个函数当成是 echo命令。
不用泛型的话,这个函数可能是下面这样:
function identity(arg: number): number {
return arg;
}
或者,我们使用any类型来定义函数:
function identity(arg: any): any {
return arg;
}
使用any类型会导致这个函数可以接收任何类型的arg参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。如果我们传入一个数字,我们只知道任何类型的值都有可能被返回。
因此,我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。
function identity<T>(arg: T): T {
return arg;
}
我们给identity添加了类型变量T。 T帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。 之后我们再次使用了 T当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。 这允许我们跟踪函数里使用的类型的信息。
我们把这个版本的identity函数叫做泛型,因为它可以适用于多个类型。 不同于使用 any,它不会丢失信息,像第一个例子那像保持准确性,传入数值类型并返回数值类型。
我们定义了泛型函数后,可以用两种方法使用。 第一种是,传入所有的参数,包含类型参数:
let output = identity<string>("myString"); // type of output will be 'string'
这里我们明确的指定了T是string类型,并做为一个参数传给函数,使用了<>括起来而不是()。
我们也可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以。
function add<T, U>(a: T, b: U): Array<T | U> {
return [a, b];
}
add<number, string>(1, '1');
定义泛型接口
声明接口的时候 在名字后面加一个<参数>
使用的时候传递类型
interface A<T> {
(arg: T): T;
}
const f: A<number> = (a: number) => {
return a;
}
对象字面量泛型
let f = function <T>(a: T, b: T): Array<T> {
return [a, b]
}
f<number>(1, 2)
泛型约束
我们期望在一个泛型的变量上面,获取其length参数,但是,有的数据类型是没有length属性的
function getLegnth<T>(arg:T) {
return arg.length
}
、
arg如果不是数组类型就没有length属性
这时候我们就可以使用泛型约束
于是,我们就得对使用的泛型进行约束,我们约束其为具有length属性的类型,这里我们会用到interface,代码如下
interface A{
length:number
}
function getLegnth<T extends A>(arg:T) {
return arg.length
}
getLegnth<string>('123')
使用keyof 约束对象
其中使用了TS泛型和泛型约束。首先定义了T类型,并使用extends关键字继承object类型的子类型,然后使用keyof操作符获取T类型的所有键,它的返回类型是联合类型,最后利用extends关键字约束K类型,必须为keyof T联合类型的子类型
let obj = {
name: 'zl',
age: 18
}
type keys = keyof typeof obj; // keys为联合类型的别名keys = 'name' | 'age'
function f<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
console.log(f(obj, 'name')); //zl
泛型类
声明方法跟函数类似,名称后面定义<类型>
使用的时候确定类型new A<number>()
class A<T>{
arr:T[]=[];
add(a:T,b:T):T[]{
return [a,b];
}
}
let s=new A<number>();
console.log(s.add(1,2));
s.arr=[1,2,3]
console.log(s.arr);
标签:function,TypeScript,return,泛型,使用,笔记,类型,arg,之泛
From: https://blog.csdn.net/qq_39237831/article/details/137028443