襄阳网站建设公司招聘,宜春网站建设,工程建筑模板生产厂家,网站搬家 备案文章目录 1、介绍2、泛型函数- 定义泛型- 使用泛型 3、泛型接口3.1 约束对象形状#xff1a;3.2 泛型接口作为函数类型3.3 泛型接口作为字典的类型3.4 泛型接口与多个类型参数 4、泛型类4.1 定义一个泛型类4.2 定义多个类型参数 5、泛型约束5.1 定义约束条件5.2 在泛型约束中使… 文章目录 1、介绍2、泛型函数- 定义泛型- 使用泛型 3、泛型接口3.1 约束对象形状3.2 泛型接口作为函数类型3.3 泛型接口作为字典的类型3.4 泛型接口与多个类型参数 4、泛型类4.1 定义一个泛型类4.2 定义多个类型参数 5、泛型约束5.1 定义约束条件5.2 在泛型约束中使用类型参数5.3 在泛型里使用类类型- 使用构造签名- 使用类类型的泛型函数- 泛型类和工厂函数 1、介绍
定义 泛型是指在定义函数、接口或类的时候不预先指定具体类型而是在使用的时候再指定类型
语法 泛型的语法是 里写类型参数一般可以用 T 来表示 泛型中的 T 就像一个占位符、或者说一个变量在使用的时候可以把定义的类型像参数一样传入它可以原封不动地输出
泛型的好处
函数和类可以轻松地支持多种类型增强程序的拓展性不必写冗长的联合类型增强代码的可读性灵活控制类型之间的约束
为什么需要泛型 不使用泛型
function identity(arg: number): number {return arg;
}function identity(arg: string): string {return arg;
}或者使用any类型来定义函数
function identity(arg: any): any {return arg;
}使用any类型会导致这个函数可以接收任何类型的arg参数这样就丢失了一些信息传入的类型与返回的类型应该是相同的 因此我们需要一种方法使返回值的类型与传入参数的类型是相同的
2、泛型函数
- 定义泛型
function identityT(arg: T): T {return arg;
}
// T帮助我们捕获用户传入的类型比如number之后我们就可以使用这个类型- 使用泛型
定义了泛型函数后两种方法使用 1传入所有的参数包含类型参数
let output identitystring(myString); // type of output will be string2利用了类型推论 – 即编译器会根据传入的参数自动地帮助我们确定T的类型
let output identity(myString); // type of output will be string3、泛型接口
泛型接口允许你在定义接口的时候不具体指明某些类型并且在实现接口或者使用接口的时候再指定这些类型 泛型接口可以用来约束对象的形状、数组内容、函数签名等多种用途。
3.1 约束对象形状
定义
interface IdentityT {value: T;getMessage(): string;
}使用
// 使用接口并指定 T 为 number 类型
let numberIdentity: Identitynumber {value: 42,getMessage() {return Value is a number: ${this.value};}
};// 使用接口并指定 T 为 string 类型
let stringIdentity: Identitystring {value: Hello,getMessage() {return Value is a string: ${this.value};}
};3.2 泛型接口作为函数类型
定义
interface GenericFnT {(arg: T): T;
}使用
// 实现接口的函数 - 返回值类型与入参数类型相同
const identity: GenericFnnumber (arg) arg;3.3 泛型接口作为字典的类型
定义
interface DictionaryT {[key: string]: T;
}使用
// 字典创建时确定其值应为字符串类型
let keys: Dictionarystring {key1: value1,key2:value2,
};// 字典创建时确定其值应为数组类型
let objectList: Dictionaryobject[] {list1: [{}, {}],list2: [{}, {}, {}]
};3.4 泛型接口与多个类型参数
定义
interface PairK, V {key: K;value: V;
}使用
let pair: Pairstring, number {key: age,value: 35
};4、泛型类
泛型类是具有一个或多个泛型类型参数的类这些类型参数在类实例化的时候被指定
4.1 定义一个泛型类
定义
class GenericClassT {// property 的类型为 Tvalue: T;// 构造函数参数的类型为 Tconstructor(value: T) {this.value value;}// 方法返回值的类型为 TgetValue(): T {return this.value;}
}使用
// 使用字符串类型实例化类
const stringInstance new GenericClassstring(Hello, TypeScript!);
console.log(stringInstance.getValue()); // 输出: Hello, TypeScript!// 使用数字类型实例化类
const numberInstance new GenericClassnumber(42);
console.log(numberInstance.getValue()); // 输出: 42// 使用数组类型实例化类
const arrayInstance new GenericClassstring[]([apple, banana, cherry]);
console.log(arrayInstance.getValue()); // 输出: [apple, banana, cherry]4.2 定义多个类型参数
定义
class KeyValueClassK, V {key: K;value: V;constructor(key: K, value: V) {this.key key;this.value value;}getKeyValue(): string {return Key: ${this.key}, Value: ${this.value};}
}使用
// 使用类
const keyValuePair new KeyValueClassnumber, string(1, One);
console.log(keyValuePair.getKeyValue()); // 输出: Key: 1, Value: One5、泛型约束
5.1 定义约束条件
定义一个接口来描述约束条件
// 创建一个包含 .length 属性的接口
interface Lengthwise {length: number;
}// 使用这个接口和extends关键字来实现约束
function loggingIdentityT extends Lengthwise(arg: T): T{return arg;
}现在这个泛型函数被定义了约束因此它不再是适用于任意类型
loggingIdentity(3); // Error, number doesnt have a .length property我们需要传入符合约束类型的值必须包含必须的属性
loggingIdentity({length: 10, value: 3});5.2 在泛型约束中使用类型参数
你可以声明一个类型参数且它被另一个类型参数所约束 定义
function getPropertyT, K extends keyof T(obj: T, key: K) {return obj[key];
}使用
const obj {name: Alice,age: 25,hasPet: false
};// 正常使用
const name getProperty(obj, name); // 正确name 的类型被推断为 string
const age getProperty(obj, age); // 正确age 的类型被推断为 number// 错误使用
const weight getProperty(obj, weight); // 错误weight 不存在于obj类型上5.3 在泛型里使用类类型
在 TypeScript 中利用泛型来使用类类型你可以创建一个函数其参数或返回值的类型可以是一个类构造器类的静态部分或类的实例类的实例部分)
- 使用构造签名
function createInstanceT(c: { new (): T }): T {return new c();
}- 使用类类型的泛型函数
例如假设我们有一个类 Animal 和一个工厂函数我们想让这个函数返回一个 Animal 类型的实例对象
class Animal {name: string;constructor(name: string) { this.name name; }move(meters: number) {console.log(${this.name} moved ${meters}m.);}
}// createInstance 函数可以接受任何具有单个字符串参数构造函数的类
function createInstanceT(c: { new (name: string): T }): T {return new c(Animal Name);
}let animal: Animal createInstance(Animal);
animal.move(5); // 输出: Animal Name moved 5m.- 泛型类和工厂函数
你也可以在泛型类中使用类类型如下所示
class BeeKeeper {hasMask: boolean true;
}class ZooKeeper {nameTag: string Mikle;
}class Animal {numLegs: number 4;
}class Bee extends Animal {keeper: BeeKeeper new BeeKeeper();
}class Lion extends Animal {keeper: ZooKeeper new ZooKeeper();
}function createInstanceA extends Animal(c: new () A): A {return new c();
}// 创建 Lion 实例
createInstance(Lion).keeper.nameTag; // 类型检查 OK
// 创建 Bee 实例
createInstance(Bee).keeper.hasMask; // 类型检查 OK