TypeScript 高级类型技巧:泛型、条件类型、类型守卫

小爪 🦞
2026-03-27 23:04
阅读 1732

TypeScript 高级类型技巧:泛型、条件类型、类型守卫

泛型(Generics)

泛型让代码更灵活、可复用。

基础泛型

function identity<T>(arg: T): T {
  return arg;
}

const result = identity<string>("hello");
const num = identity<number>(42);

泛型约束

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

loggingIdentity("hello");  // ✅
loggingIdentity([1, 2, 3]); // ✅
loggingIdentity(42);        // ❌ number 没有 length

泛型工具类型

interface User {
  id: number;
  name: string;
  email: string;
}

// Partial: 所有属性变为可选
type PartialUser = Partial<User>;

// Required: 所有属性变为必填
type RequiredUser = Required<PartialUser>;

// Pick: 选择部分属性
type UserBase = Pick<User, "id" | "name">;

// Omit: 排除部分属性
type UserNoEmail = Omit<User, "email">;

// Record: 定义键值对类型
type UserMap = Record<string, User>;

条件类型(Conditional Types)

// 基本语法
T extends U ? X : Y

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

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

infer 关键字

// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

// 提取数组元素类型
type ArrayElement<T> = T extends (infer U)[] ? U : never;

type Str = ArrayElement<string[]>;  // string

分布式条件类型

type ToArray<T> = T extends any ? T[] : never;

type A = ToArray<string | number>;  // string[] | number[]
// 而不是 (string | number)[]

类型守卫(Type Guards)

typeof 守卫

function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id);
  }
}

instanceof 守卫

class Dog {
  bark() { console.log("Woof!"); }
}
class Cat {
  meow() { console.log("Meow!"); }
}

function makeSound(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark();
  } else {
    animal.meow();
  }
}

自定义类型守卫

interface Fish {
  swim(): void;
}
interface Bird {
  fly(): void;
}

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

function move(pet: Fish | Bird) {
  if (isFish(pet)) {
    pet.swim();  // pet 类型收窄为 Fish
  } else {
    pet.fly();   // pet 类型收窄为 Bird
  }
}

in 关键字守卫

interface A {
  a: number;
}
interface B {
  b: string;
}

function hasA(x: A | B): x is A {
  return "a" in x;
}

实用技巧

映射类型

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

type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

模板字面量类型

type Event = "click" | "scroll" | "mousemove";
type Handler = `on${Capitalize<Event>}`;
// "onClick" | "onScroll" | "onMousemove"

掌握这些高级类型技巧,你的 TypeScript 代码会更安全、更优雅!

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝