高阶类型
泛型
可以在编写代码时使用参数化类型,使得代码可以适用于多种不同类型的数据
// 函数泛型
function identity<T>(arg: T): T {
return arg;
}
// 使用
let output1 = identity<string>("hello"); // output1 的类型为 string
let output2 = identity<number>(123); // output2 的类型为 number
// 接口泛型
interface Param<T> {
id: number;
data: T
}
// 使用
const param1: Param<number[]> = {id: 1, data: [1,2,3]}
const param2: Param<string> = {id: 1, data: 'TEST STRING'}
联合类型
表示这个类型可以是连接的类型中的任意一个
type NumericType = number | bigint;
interface Circle {
area: bigint;
radius: number;
}
interface Rectangle {
area: number;
width: number;
height: number;
}
type Shape = Circle | Rectangle;
declare const s: Shape
s.area; // bigint | number
s.width; // 错误
s.radius; // 错误
// 解决方案:使用in操作符或者类型断言
if ('width' in s) {
console.log(s.width)
}
(s as Circle).radius
交叉类型
对多个类型进行合并,表示这个类型同时具有所有连接的类型的特性
interface User {
name: string;
age: number;
}
interface Admin {
name: string;
role: string;
}
type UserAdmin = User & Admin;
const userAdmin: UserAdmin = { name: "Alice", age: 30, role: "admin" };
// UserAdmin 是 User 和 Admin 的交叉类型,表示一个用户和管理员的组合类型。
// userAdmin 对象必须同时包含 name、age 和 role 属性
元组
是一种表示具有固定数量和类型的元素的数组类型。元组类型使用方括号 [] 来表示,其中每个元素的类型由逗号分隔
// 示例1
let x: [string, number];
x = ["hello", 10]; // OK
x = [10, "hello"]; // Error
// 示例2
// Point 是一个包含两个数字元素的元组类型
type Point = [number, number];
function distance(p1: Point, p2: Point) {
const dx = p1[0] - p2[0];
const dy = p1[1] - p2[1];
return Math.sqrt(dx ** 2 + dy ** 2);
}
索引类型
// 语法
type PropertyType = ObjectType[Key];
// 示例
type Person = {
name: string;
age: number;
location: string;
}
type NameType = Person['name']; // string
type NameOrAgeType = Person['name' | 'age']; // string | number
映射类型
是一种强大的工具,可以基于已有类型创建新的类型。通过映射类型,你可以对一个类型的所有属性进行变换或操作
// 语法
type MappedType<T> = {
[P in keyof T]: T[P];
};
// 常见的工具类型就是通过映射类型实现的。举例:
// Partial
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 示例
interface Person {
name: string;
age: number;
}
type PartialPerson = Partial<Person>;
// PartialPerson 的类型为 { name?: string; age?: number; }
// Required
type Required<T> = {
[P in keyof T]-?: T[P];
};
// 示例
interface PartialPerson {
name?: string;
age?: number;
}
type RequiredPerson = Required<PartialPerson>;
// RequiredPerson 的类型为 { name: string; age: number; }
// Readonly
type Readonly<T> = {
[P in keyof T]: Readonly<T[P]>;
};
// 示例
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
// ReadonlyPerson 的类型为 { readonly name: string; readonly age: number; }
工具类型
Pick<T,K>
从对象类型中选取给定的属性
interface A {
x: number;
y: number;
}
type T0 = Pick<A,'x'> // {x: number}
type T1 = Pick<A, 'x'| 'y'> // {x: number, y: number}
Omit<T,K>
从对象类型中剔除给定的属性
interface A {
x: number;
y: number;
}
type T0 = Omit<A,'y'>// {x: number}
type T1 = Omit<A, 'x'| 'y'> // {x: number, y: number}
// Omit的实现
type Omit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P];
};
Exclude<T,U>
从联合类型中剔除给定的属性
type T = 'a' | 'b' | 'c'
type U = 'b' | 'c'
type T0 = Exclude<T,U> // 'a'
Extract<T,U>
从联合类型中选取给定的属性
type T = 'a' | 'b' | 'c'
type U = 'b' | 'c'
type M = 'b' | 'd'
type T0 = Extract<T,U> // 'b' | 'c'
type T1 = Extract<T,M> // 'b'
类型查询操作
typeof
typeof 关键字用于获取一个值的类型。例如:
const x = 42;
type XType = typeof x; // XType 的类型为 number
keyof
keyof 关键字用于获取一个类型的所有属性名。例如:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // PersonKeys 的类型为 "name" | "age"
in
in 关键字用于判断一个属性名是否属于一个类型。例如:
interface Person {
name: string;
age: number;
}
type HasName = "name" in Person; // HasName 的类型为 true
type HasAddress = "address" in Person; // HasAddress 的类型为 false
extends
extends 关键字用于判断一个类型是否是另一个类型的子类型。例如:
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
type IsDog = Dog extends Animal ? true : false; // IsDog 的类型为 true
type IsAnimal = Animal extends Dog ? true : false; // IsAnimal 的类型为 false
typeof keyof
typeof keyof 结合使用可以用于获取一个值的所有属性名。例如:
const person = {
name: "Alice",
age: 30,
location: "New York"
};
type PersonKeys = typeof person[keyof typeof person]; // PersonKeys 的类型为 "name" | "age" | "location"