使用接口和类实现泛型
泛型只是一种将类型传递给组件的方法。
尝试将泛型与接口、函数和类结合使用。
声明泛型接口
定义一个 System 接口 具有两个属性 value 和 message
interface System<T, U> {
value: T;
message: U;
}
使用 System 接口作为对象类型来声明两个变量。
let returnNumber: System<number, string> = {
value: 25,
message: 'Hello!'
}
console.log(returnNumber) //输出 { value: 25, message: 'Hello!' }
let returnString: System<string, number> = {
value: 'Hello!',
message: 25
}
将泛型接口声明为函数类型
定义一个 System2 的接口,该接口包含方法的泛型签名(value: T, message: U): T 注意该方法没有名字,可以将其应用于具有匹配的类型签名的任何函数。
// 函数类型的 泛型接口
interface System2<T, U> {
(value: T, message: U): T;
}
//泛型函数
function system2<T, U>(value: T, message: U): T {
console.log(value, message);
return value;
}
// 函数类型变量
// 声明了一个fx变量 类型是 泛型接口System2 并初始化为 system2函数
let fx: System2<number, string> = system2;
let fy = fx(100, 'wdk'); //Ok
let fz = fx('wdk', 100); //错误 类型不对
将泛型接口声明为类类型
可以声明泛型接口并在类中实现它。
//将泛型接口声明为类类型
interface System3<T, U> {
value: T, //属性类型的泛型类型变量
message: U,
run(): T,
}
//实现接口
class system3<X, Y> implements System3<X, Y>{
value: X;
message: Y;
constructor(value: X, message: Y) {
this.value = value;
this.message = message;
}
run(): X {
console.log(this.value, this.message);
return this.value;
}
}
let s3 = new system3<number, string>(100, 'wdk');
s3.value = '123'; // 不能将类型“string”分配给类型“number”
s3.run(); //输出 100 wdk
console.log(s3.value, s3.message) //输出 100 wdk
定义泛型类
声明没有接口的泛型类
//泛型类
class wdk<T, U>{
private _value: T;
private _message: U;
constructor(value: T, message: U) {
this._value = value;
this._message = message;
}
run(): T {
console.log(this._value, this._message);
return this._value;
}
}
let wdkModel = new wdk<number, string>(100, 'wdk');
wdkModel.run(); //输出 100 wdk
使用自定义类型和类实现泛型
-
泛型与基本类型集合使用。
-
泛型与自定义类型和类结合使用。
基类 Car 类
子类 ElectricCar , Truck
定义一个函数 accelerate 参数 为 Car 的泛型实例然后将其返回。
//自定义类型和类 实现泛型
class Car {
make: string = 'car';
doors: number = 4;
}
class ElectricCar extends Car {
make = 'electric car';
doors = 4;
}
class Truck extends Car {
make = 'truck';
doors = 2;
}
function accelerate<T extends Car>(car: T): T {
console.log(car.make + ' accelerating...');
return car;
}
let ecar = new ElectricCar;
accelerate<ElectricCar>(ecar);
let tcar = new Truck;
accelerate<Truck>(tcar);
对自定义类型和类使用泛型约束
使用泛型约束来限制类型
上面的例子 通过将“T 必须扩展 Car”的限制附加到 T 类型来对其进行约束
知识检查
-
使用泛型时,可以限制类型变量可接受的类型范围。 这称之为什么?
泛型约束 (泛型约束限制类型变量可接受的类型,而不是接受任何可能的类型)
-
与泛型一起使用的最佳操作类型有哪些?
可对各种数据执行的操作。(由于可能是任何类型,因此 TypeScript 会引发错误,以阻止某些类型不支持的操作。 出于此原因,最好将泛型与可处理各种数据的操作结合使用。)
-
使用泛型和使用 any 类型之间有何区别?
使用泛型可进行类型检查,而使用 any 类型则不可以。(类型检查是泛型与 any 类型之间的主要区别。)