使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。
<T>
在前面声明
function identity<T>(arg: T): T {
return arg;
}
//使用方法1,:用之前声明
let output = identity<string>("myString"); // myString
//使用方法2,:类型推论
let output = identity("myString"); // myString
// 可以定义数组内的值得类型
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
function identity<T>(arg: T): T {
return arg;
}
//1. 不同的泛型,只要数量和使用方式可以对应上就可以
let myIdentity: <U>(arg: U) => U = identity;
//2. 使用带有 调用签名 的对象字面量来定义泛型函数
let myIdentity: {<T>(arg: T): T} = identity;
泛型接口
function identity<T>(arg: T): T {
return arg;
}
- 参数放在调用签名
里
interface GenericIdentityFn {
<T>(arg: T): T;
}
let myIdentity: GenericIdentityFn = identity;
- 参数放在调用签名
外
interface GenericIdentityFn <T>{
(arg: T): T;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
let stringNumeric = new GenericNumber<string>();
泛型约束
我们需要传入符合约束类型的值,必须包含必须的属性:<T extends 接口>
表示 T 型 一定要满足接口的定义
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
// Now we know it has a .length property, so no more error
return arg;
}
多个参数时也可以在泛型约束中使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
let obj = { a: 1, b: 2, c: 3 }
getProperty(obj, 'a') // success
类类型
new() 表示 构造函数类型
直接使用构造函数(类) 的是实例类型
表示c是构造函数没有参数的T类
的类型
function create<T>(c: {new(): T; }): T {
return new c();
}
createInstance函数的参数是构造函数没有参数的A类的类型。
class BeeKeeper {
hasMask: boolean;
}
class ZooKeeper {
nametag: string;
}
class Animal {
numLegs: number;
}
class Bee extends Animal {
keeper: BeeKeeper;
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}
createInstance(Bee).keeper.hasMask; // typechecks!