TypeScript 高级技巧:让代码更优雅

分享一些实用的 TypeScript 高级技巧,包括类型体操、条件类型、映射类型等,帮助你写出更健壮的代码

2024-02-20

条件类型

条件类型是 TypeScript 中非常强大的特性,它允许我们根据类型关系来选择类型。

type IsString<T> = T extends string ? true : false;

type A = IsString<string>;  // true
type B = IsString<number>;  // false

映射类型

映射类型可以基于已有类型创建新类型,是类型体操的基础。

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Partial<T> = {
  [P in keyof T]?: T[P];
};

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

infer 关键字

infer 用于在条件类型中推断类型,非常有用:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: 'Alice' };
}

type User = ReturnType<typeof getUser>;
// { id: number; name: string; }

模板字面量类型

模板字面量类型可以创建字符串联合类型:

type EventName<T extends string> = `on${Capitalize<T>}`;

type ClickEvent = EventName<'click'>;  // "onClick"
type HoverEvent = EventName<'hover'>;  // "onHover"

实用工具

一些实用的类型工具函数:

// 深 Readonly
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object 
    ? DeepReadonly<T[P]> 
    : T[P];
};

// 非空对象类型
type NonNullable<T> = T extends null | undefined ? never : T;

// 对象键值反转
type ReverseMapping<T extends Record<string, string>> = {
  [K in keyof T as T[K]]: K;
};

总结

TypeScript 的类型系统非常灵活,善用这些技巧可以让代码更加健壮、可维护。不过也要记住,类型体操是为了更好地表达代码意图,而不是为了炫技。保持简洁,适度使用。

"类型是文档,是契约,是测试。" — 匿名