泛型是一种创建可重用组件的工具,它可以支持多种类型的数据,而不是单一的类型。使用泛型可以创建灵活且类型安全的代码。
// 不使用泛型
function identity(arg: number): number {
return arg;
}
// 使用泛型
function identity(arg: T): T {
return arg;
}
// 使用方式1:明确指定类型
let output1 = identity("myString");
// 使用方式2:类型推断
let output2 = identity("myString");
// 泛型函数类型
function identity(arg: T): T {
return arg;
}
let myIdentity: (arg: T) => T = identity;
// 使用对象字面量形式
let myIdentity2: { (arg: T): T } = identity;
// 使用接口定义
interface GenericIdentityFn {
(arg: T): T;
}
let myIdentity3: GenericIdentityFn = identity;
class GenericNumber {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) {
return x + y;
};
let stringNumeric = new GenericNumber();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) {
return x + y;
};
使用 extends 关键字约束泛型类型:
interface Lengthwise {
length: number;
}
function loggingIdentity(arg: T): T {
console.log(arg.length); // 现在可以访问length属性
return arg;
}
loggingIdentity({ length: 10, value: 3 }); // 正确
loggingIdentity(3); // 错误:number没有length属性
function getProperty(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a"); // 正确
getProperty(x, "m"); // 错误:m不是x的属性
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 createInstance(c: new () => A): A {
return new c();
}
createInstance(Lion).keeper.nametag;
createInstance(Bee).keeper.hasMask;
// Partial - 将所有属性变为可选
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial) {
return { ...todo, ...fieldsToUpdate };
}
// Readonly - 将所有属性变为只读
const todo: Readonly = {
title: "Delete inactive users",
description: "Clean up database"
};
todo.title = "Hello"; // 错误:只读属性
// Record - 创建键值对类型
type PageInfo = {
title: string;
};
type Page = "home" | "about" | "contact";
const nav: Record = {
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" }
};
function pair(first: T, second: U): [T, U] {
return [first, second];
}
let result = pair("age", 25);
let result2 = pair("name", "Alice"); // 类型推断