TypeScript 中的高级类型

在 TypeScript 里,高级类型是提升类型系统灵活性和表达能力的重要工具,下面介绍常见高级类型及其用法。

交叉类型

通过 & 运算符将多个类型合并为一个类型,新类型包含所有类型的特性。

interface Person {
  name: string;
}

interface Employee {
  employeeId: number;
}

type PersonEmployee = Person & Employee;
const personEmployee: PersonEmployee = {
  name: 'Alice',
  employeeId: 123
};

联合类型

通过 | 运算符定义一个值可以是几种类型之一。

function printId(id: number | string) {
  console.log(id);
}

printId(123);
printId('a');

类型别名

使用 type 关键字定义类型别名。

type Point = { x: number; y: number };
const point: Point = { x: 1, y: 2 
};

类型索引

通过keyof 操作符能获取一个对象类型所有属性名构成的联合类型。

interface Person {
  name: string;
  age: number;
}

// PersonKey 类型为 "name" | "age" 
type PersonKey = keyof Person;

function getProperty(person: Person, key: PersonKey) {
  return person[key];
}

const person: Person = { name: 'Alice', age: 30 };
// 正确
const name = getProperty(person, 'name'); 

// 报错,'phone' 不在 PersonKey 类型中
//const invalid = getProperty(person, 'phone'); 

类型约束

使用 extends 关键字可以约束泛型类型的取值范围。

约束泛型参数为特定类型
//extends类型约束,这里要求 T 类型必须包含 length 属性
function getLength<T extends { length: number }>(value: T): number {
  return value.length;
}

// 正确,字符串有 length 属性
const strLength = getLength('hello');

// 正确,数组有 length 属性
const arrLength = getLength([1, 2, 3]);

// 报错,数字没有 length 属性
//const numLength = getLength(123); 
约束泛型参数为对象属性类型
interface Person {
  name: string;
  age: number;
}

// T 约束为 Person 类型的属性名
function getProperty<T extends keyof Person>(person: Person, key: T): Person[T] {
  return person[key];
}

const person: Person = { name: 'Alice', age: 30 };
// 正确
const name = getProperty(person, 'name');
// 正确
const age = getProperty(person, 'age');

// 报错,'phone' 不是 Person 的属性名
// const invalid = getProperty(person, 'phone'); 

映射类型

通过 in 关键字可以对类型进行映射操作。

语法
type MappedType<T> = {
  [P in keyof T]: T[P];
};
可选类型的映射
//将 Person 的所有属性变为可选
interface Person {
  name: string;
  age: number;
}

type OptionalPerson = { [K in keyof Person]?: Person[K] };
const optionalPerson: OptionalPerson = { name: 'Alice' };

//只读属性映射
interface Point {
  x: number;
  y: number;
}
只读属性映射
interface Point {
  x: number;
  y: number;
}

// 将 Point 的所有属性变为只读
type ReadonlyPoint = { readonly [K in keyof Point]: Point[K] };

const readonlyPoint: ReadonlyPoint = { x: 10, y: 20 };

// 报错,属性只读
// readonlyPoint.x = 30; 
属性值类型转换
interface NumberConfig {
  min: number;
  max: number;
}

// 将 NumberConfig 的所有属性值类型转换为 string
type StringConfig = { [K in keyof NumberConfig]: string };

const stringConfig: StringConfig = { min: '0', max: '100' };

条件类型

条件类型是一种强大的类型工具,借助条件表达式来动态确定类型。它的语法类似 JavaScript 中的三元运算符,基本形式为 T extends U ? X : Y。

// 定义一个条件类型,判断 T 是否为数组类型
type IsArray<T> = T extends any[] ? true : false;

// NumberIsArray 类型为 false
type NumberIsArray = IsArray<number>;

// StringArrayIsArray 类型为 true
type StringArrayIsArray = IsArray<string[]>;

//TypeScript中内置工具类型都借助了条件类型实现
// Exclude<T, U>:从 T 中排除可以赋值给 U 的类型
type Exclude<T, U> = T extends U ? never : T;

// NonNullable<T>:从 T 中排除 null 和 undefined
type NonNullable<T> = T extends null | undefined ? never : T;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值