TypeScript Type 类型别名详解

123 阅读3分钟

TypeScript Type 类型别名详解

目录

  1. 概述
  2. 基本用法
  3. 高级用法
  4. 与 Interface 的区别
  5. 最佳实践
  6. 实际应用场景

概述

type 关键字用于创建类型别名,可以为任何类型定义一个新名字,包括原始类型、联合类型、交叉类型、元组等。

为什么使用 type?

  • 提高代码可读性
  • 减少重复代码
  • 更灵活的类型定义
  • 支持复杂的类型操作

基本用法

1. 基本类型别名

// 简单类型别名
type UserID = string;
type Age = number;
type IsActive = boolean;

// 使用类型别名
let userId: UserID = "u123";
let userAge: Age = 25;
let active: IsActive = true;

2. 对象类型

// 对象类型别名
type User = {
  id: string;
  name: string;
  age: number;
  email?: string;  // 可选属性
};

// 使用对象类型
const user: User = {
  id: "1",
  name: "John",
  age: 30
};

3. 联合类型

// 联合类型
type Status = "pending" | "approved" | "rejected";
type ID = string | number;

// 使用联合类型
let status: Status = "pending";  // 只能是这三个值之一
let id: ID = "123";  // 可以是字符串或数字

高级用法

1. 泛型类型别名

// 泛型类型别名
type Container<T> = {
  value: T;
  tag: string;
};

// 使用泛型类型
const numberContainer: Container<number> = {
  value: 123,
  tag: "number"
};

const stringContainer: Container<string> = {
  value: "hello",
  tag: "string"
};

2. 交叉类型

type Person = {
  name: string;
  age: number;
};

type Employee = {
  company: string;
  role: string;
};

// 交叉类型
type EmployeeInfo = Person & Employee;

// 使用交叉类型
const employee: EmployeeInfo = {
  name: "John",
  age: 30,
  company: "Tech Corp",
  role: "Developer"
};

3. 条件类型

// 条件类型
type IsString<T> = T extends string ? true : false;
type IsNumber<T> = T extends number ? true : false;

// 使用条件类型
type Result1 = IsString<"hello">;  // true
type Result2 = IsString<123>;      // false

4. 映射类型

// 映射类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

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

// 使用映射类型
type ReadonlyUser = Readonly<User>;
type OptionalUser = Optional<User>;

与 Interface 的区别

1. 语法差异

// Interface
interface Animal {
  name: string;
  age: number;
}

// Type
type Animal = {
  name: string;
  age: number;
};

2. 扩展方式

// Interface 扩展
interface Animal {
  name: string;
}
interface Dog extends Animal {
  breed: string;
}

// Type 扩展
type Animal = {
  name: string;
}
type Dog = Animal & {
  breed: string;
};

3. 合并声明

// Interface 可以合并声明
interface User {
  name: string;
}
interface User {
  age: number;
}
// 结果:User 有 name 和 age 属性

// Type 不能合并声明
type User = {
  name: string;
}
type User = {  // 错误:重复的标识符
  age: number;
}

最佳实践

1. 命名约定

// 使用描述性名称
type HttpResponse<T> = {
  data: T;
  status: number;
  message: string;
};

// 使用后缀表示类型种类
type UserProps = {
  // ...props for user component
};
type UserState = {
  // ...state for user component
};

2. 组合类型

// 基础类型
type BaseEntity = {
  id: string;
  createdAt: Date;
  updatedAt: Date;
};

// 组合��用
type User = BaseEntity & {
  name: string;
  email: string;
};

type Product = BaseEntity & {
  title: string;
  price: number;
};

3. 类型保护

type Success<T> = {
  type: 'success';
  data: T;
};

type Error = {
  type: 'error';
  error: string;
};

type Result<T> = Success<T> | Error;

function handleResult(result: Result<User>) {
  if (result.type === 'success') {
    console.log(result.data.name);  // 类型安全
  } else {
    console.log(result.error);      // 类型安全
  }
}

实际应用场景

1. React 组件类型

type Props = {
  title: string;
  children: React.ReactNode;
  onClick?: () => void;
};

const Button: React.FC<Props> = ({ title, children, onClick }) => {
  return (
    <button onClick={onClick}>
      {title}
      {children}
    </button>
  );
};

2. API 响应类型

type ApiResponse<T> = {
  data: T;
  metadata: {
    page: number;
    total: number;
  };
};

type User = {
  id: string;
  name: string;
};

async function fetchUsers(): Promise<ApiResponse<User[]>> {
  const response = await fetch('/api/users');
  return response.json();
}

3. 状态管理

type State = {
  user: User | null;
  isLoading: boolean;
  error: string | null;
};

type Action =
  | { type: 'LOGIN_REQUEST' }
  | { type: 'LOGIN_SUCCESS'; payload: User }
  | { type: 'LOGIN_FAILURE'; payload: string };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'LOGIN_REQUEST':
      return { ...state, isLoading: true };
    case 'LOGIN_SUCCESS':
      return { ...state, isLoading: false, user: action.payload };
    case 'LOGIN_FAILURE':
      return { ...state, isLoading: false, error: action.payload };
  }
}

总结

  1. type 的优点:

    • 可以为任何类型创建别名
    • 支持复杂的类型操作
    • 更好的类型推断
    • 更灵活的类型定义
  2. 使用场景:

    • 联合类型和交叉类型
    • 工具类型
    • 条件类型
    • 复杂的类型定义
  3. 最佳实践:

    • 使用描述性名称
    • 合理组合类型
    • 保持类型简单清晰
    • 适当使用泛型 在这里插入图片描述