泛型
声明:这篇文章可能没有任何意义,因为代码实例都是官网上的
本人只是边学习,边记录过程,以及进行改写。如有不明,可直接移步官方文档
初识泛型
官方的两个例子
例子一:我们使用 any
类型来定义函数:输入任意类型的参数,返回任意类型的值
function identity(arg: any): any {return arg;}
console.log(identity(100)); // 100
使用
any
类型会导致这个函数可以接收任何类型的arg
参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。如果我们传入一个数字,我们只知道任何类型的值都有可能被返回。
例子二:改写一下
function identity(arg: number): number {return arg;}
console.log(identity(100)); // 100
此时我们只能传入 number 类型的数据,返回的也是 number
但是,我们要的效果是,传入一种数据类型的参数,返回的只能是那种,可我们将他固定为 number 显然不合适。比如我们要求 string 也适合
此时我们引入 类型变量 T
function identity<T>(arg: T): T {return arg;}
此时我们可以想获取自己想要的任何类型 如下:我们传入的参数是 string 类型, 返回的也是 string 类型
let id: string = identity<string>("hello world");
console.log(id); // hello world
也可以直接使用类型推断,简略代码
// let id:number = identity<number>(101010);
let id = identity(101010); // // 等同于上一行代码 类型推断
console.log(id)
个人觉得还是长一点具有可读性,不需要编译器进行类型推断。既然使用了typescript
,自然要让它看起来更严格。
使用泛型变量
泛型的数组,打印它的长度
function fun<T>(arg: T[]): void {console.log(arg.length)
}
// fun<number>([1,2,4]); // 3
fun<string>(['a','b','c', 'd']); // 4
函数类型
function identity<T>(arg: T): T {return arg;}
let myIdentity: <T>(arg: T) => T = identity;
等同于 js 中的
function identity(arg) {return arg;}
let myIdentity = identity;
其实就是函数声明和使用
或许下面这样写更让我明白
function identity<T>(arg: T): T {return arg;}
let myIdentity: {<T>(arg: T): T} = identity;
泛型的接口
上面一个列子
其实这个完全可以用接口去声明。
官方代码
字面量拿出来做为一个接口
interface GenericIdentityFn {<T>(arg: T): T;
}
function identity<T>(arg: T): T {return arg;}
let myIdentity: GenericIdentityFn = identity;
再者,把泛型参数当作整个接口的一个参数
interface GenericIdentityFn<T> {(arg: T): T;
}
function identity<T>(arg: T): T {return arg;}
let myIdentity: GenericIdentityFn<number> = identity;
等同于下面这个代码
interface GenericIdentityFn<T> {(arg: T): T;
}
let myIdentity: GenericIdentityFn<number> = function <T>(arg: T): T {return arg;}
就是函数的声明
使用这个函数,用变量来接受这个函数的返回值
// let id: string = myIdentity('102'); // Argument of type '"102"' is not assignable to parameter of type 'number'.
let id: number = myIdentity(102);
console.log(id)
后面的明天再看