TypeScript 的类型体操(Type Manipulation)是指使用 TypeScript 的类型系统来操作和转换类型,从而实现更灵活和强大的类型定义。这包括使用泛型、联合类型、交叉类型、条件类型等等。以下是一些常见的类型体操示例:
1. 泛型 (Generics)
泛型允许您创建可重用的组件,这些组件可以在多个类型中工作。
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("hello"); // 输出: string
console.log(output);
2. 联合类型 (Union Types)
联合类型允许一个变量可以是多种类型之一。
function padLeft(value: string, padding: number | string): string {
if (typeof padding === 'number') {
return Array(padding + 1).join(' ') + value;
}
if (typeof padding === 'string') {
return padding + value;
}
throw new Error(`Expected string or number, got ${padding}`);
}
console.log(padLeft("Hello", 4)); // 输出: " Hello"
console.log(padLeft("Hello", " ")); // 输出: " Hello"
3. 交叉类型 (Intersection Types)
交叉类型允许将多个类型合并为一个类型。
interface BusinessPartner {
name: string;
credit: number;
}
interface Identity {
id: number;
email: string;
}
type Employee = BusinessPartner & Identity;
let employee: Employee = {
name: "John Doe",
credit: 1000,
id: 123,
email: "john.doe@example.com"
};
console.log(employee.name); // 输出: John Doe
console.log(employee.id); // 输出: 123
4. 条件类型 (Conditional Types)
条件类型允许根据类型是否满足某些条件来选择不同的类型。
type NonNullable<T> = T extends null | undefined ? never : T;
type StringOrNumber = NonNullable<string | number | null>; // 输出: string | number
type StringOrUndefined = NonNullable<string | undefined>; // 输出: string
5. 映射类型 (Mapped Types)
映射类型允许您基于现有的类型创建一个新的类型。
type ReadOnly<T> = {
[P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadOnlyUser = ReadOnly<User>;
const user: ReadOnlyUser = {
name: "Alice",
age: 30
};
// user.name = "Bob"; // 错误: Cannot assign to 'name' because it is a read-only property.
6. 索引签名 (Index Signatures)
索引签名允许您创建具有动态属性的类型。
interface StringMap {
[key: string]: string;
}
const stringMap: StringMap = {
name: "Alice",
city: "New York"
};
console.log(stringMap.name); // 输出: Alice
7. typeof 和 keyof 操作符
typeof 操作符用于获取变量的类型,keyof 操作符用于获取对象的所有键的联合类型。
const obj = { a: 1, b: "hello" };
type ObjType = typeof obj; // 输出: { a: number; b: string; }
type Keys = keyof ObjType; // 输出: "a" | "b"
console.log(Keys); // 输出: "a" | "b"
8. infer 关键字
infer 关键字用于在条件类型中推断类型。
type ExtractPromiseValue<T> = T extends Promise<infer U> ? U : never;
type PromiseString = ExtractPromiseValue<Promise<string>>; // 输出: string
type NotPromise = ExtractPromiseValue<number>; // 输出: never
这些只是 TypeScript 中类型体操的一些基本示例。通过结合使用这些功能,您可以创建非常复杂和强大的类型系统,以满足各种开发需求。