TypeScript 的 高级类型(Advanced Types) 是指那些能够对类型进行复杂操作、组合和变换的类型系统特性。它们让你可以基于现有类型创建新类型,实现更强大、更安全的抽象。
1.交叉类型(intersection types):将多个类型合并为一个类型,新类型拥有所有类型的成员。常用于混入(mixins)或组合多个接口。
ts
interface Person {
name: string;
}
interface Employee {
employeeId: number;
}
type EmployeePerson = Person & Employee;
const worker: EmployeePerson = {
name: "Alice",
employeeId: 1001
};
2.联合类型(union types):表示一个值可以是多种类型之一。
ts
let id: string | number;
id = "abc"; //对
id = 123; //对
// id = true; //错
function printId(id: string | number) {
// 必须先进行类型检查
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id.toFixed(2));
}
}
3. 字符串字面量类型 (String Literal Types): 定义一个类型,其值只能是特定的字符串。
作用: 常用于创建类似枚举的效果,限制变量的取值范围。
ts
type Direction = "up" | "down" | "left" | "right";
let move: Direction = "up"; // OK
console.log("move",move)
// move = 'up2'; // Error: Type '"up2"' is not assignable to type 'Direction'.
4.类型别名(type aliases):为类型创建一个新名字,可以是基本类型、联合、交叉、函数等。
ts
type ID = string | number;
type Point = { x: number; y: number };
type Callback = (result: string) => void;
类型别名可以引用自己(递归类型):
type Tree<T> = {
value: T;
left: Tree<T> | null;
right: Tree<T> | null;
};
5.类型保护和类型谓词(type guards):在运行时检查类型,从而在代码块中缩小类型范围。
1.typeof(查类型)守卫
ts
function padLeft(value: string | number) {
if (typeof value === "string") {
return " " + value; // value: string
}
return Array(value).join(" ") + "0"; // value: number
}
2.instanceof 守卫
ts
//先检查:如果 error 是一个真正的 Error 对象,那我再访问它的 .message 属性。
if (error instanceof Error) {
console.log(error.message);
}
3.自定义类型守卫(使用
is)
ts
function isString(value: any): value is string {
return typeof value === "string";
}
if (isString(input)) {
// input: string
}
4. 可辨识联合(Discriminated Unions)
结合 联合类型 + 字面量类型 + 类型守卫,实现类型安全的模式匹配。
核心:通过检查一个共同的字面量属性来区分联合中的不同成员。
ts
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
function area(s: Shape): number {
switch (
s.kind // 使用 'kind' 属性作为判别式
) {
case "square":
return s.size * s.size;
case "rectangle":
return s.width * s.height;
case "circle":
return Math.PI * s.radius ** 2;
}
}
7.泛型
允许创建可以与多种类型一起工作的组件,实现类型安全的复用。
- 语法 : 使用
<T>
(T 是类型参数)。 - 应用: 函数、接口、类、类型别名。
ts
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString"); // output 是 string 类型
8.索引类型(Index Types)
利用keyof
和T[k]
操作符,实现对对象属性的动态访问和类型安全。
keyof
操作符:获取一个类型所有公共属性名的类型安全。
ts
interface Person { name: string; age: number; }
type PersonKeys = keyof Person; // "name" | "age"
T[K]
索引访问操作符:获取类型T上属性K的类型。
ts
type PersonNameType = Person['name']; // string
in操作符(映射类型):遍历联合类型中的每个属性。
typeof操作符:获取一个值的类型。
ts
const obj = { a: 1, b: 'hello' };
type ObjType = typeof obj; // { a: number; b: string }
9.映射类型(Mapped Types)
基于现有类型创建新类型,通过in操作符遍历keyof产生的联合类型。
常用内置映射类型:
- Partial
<T>
: 将 T 的所有属性变为可选。 - Readonly
<T>
: 将 T 的所有属性变为只读。 - Pick
<T, K>
: 从 T 中选取一组属性 K,构成新类型。 - Record
<K, T>
: 将 K 中的所有属性值都转换为 T 类型。 - Omit
<T, K>
: 从 T 中剔除 K 的属性。 - Exclude
<T, U>
: 从 T 中剔除可以赋值给 U 的类型。 - Extract
<T, U>
: 从 T 中提取可以赋值给 U 的类型。 - NonNullable
<T>
: 从 T 中剔除 null 和 undefined。
10.条件类型(Condditional Types)
使用T extends U ? X : Y 的语法,根据类型关系进行条件判断。
作用: 构建更复杂的类型逻辑。
ts
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
11.多态的this类型
在类中使用this作为返回类型,支持方法链式调用。
ts
class BasicCalculator {
constructor(protected value: number = 0) {}
add(operand: number): this {
this.value += operand;
return this; // 返回 this,支持链式调用
}
}