在 TypeScript 中,Pick<T, K> 是一个内置的工具类型(Utility Type),用于从类型 T 中选取指定的属性 K 来组成新的类型。关于 Pick 和 TypeScript 自带的其他工具类型,以下是详细的说明:


1. Pick<T, K> 详解

Pick<IChatMessageParams, 'chatId'> 表示从 IChatMessageParams 类型中只选取 chatId 属性。

示例:

interface IChatMessageParams {
  chatId: string;
  content: string;
  timestamp: number;
}

type ChatIdOnly = Pick<IChatMessageParams, 'chatId'>;
// 等价于:
// type ChatIdOnly = { chatId: string };

2. TypeScript 内置工具类型全集

除了 Pick,TypeScript 还提供了许多其他内置工具类型:

(1) ​**Partial<T>**​

将类型 T 的所有属性变为可选。

type PartialMessage = Partial<IChatMessageParams>;
// 等价于:
// type PartialMessage = {
//   chatId?: string;
//   content?: string;
//   timestamp?: number;
// };

(2) ​**Required<T>**​

将类型 T 的所有属性变为必选(与 Partial 相反)。

type RequiredMessage = Required<PartialMessage>;
// 恢复为所有属性必选

(3) ​**Readonly<T>**​

将类型 T 的所有属性变为只读。

type ReadonlyMessage = Readonly<IChatMessageParams>;
// 等价于:
// type ReadonlyMessage = {
//   readonly chatId: string;
//   readonly content: string;
//   readonly timestamp: number;
// };

(4) ​**Record<K, T>**​

构造一个键为 K,值为 T 的类型。

type MessageRecord = Record<'msg1' | 'msg2', IChatMessageParams>;
// 等价于:
// type MessageRecord = {
//   msg1: IChatMessageParams;
//   msg2: IChatMessageParams;
// };

(5) ​**Exclude<T, U>**​

从类型 T 中排除可以赋值给 U 的类型。

type T = 'a' | 'b' | 'c';
type Excluded = Exclude<T, 'a'>; // 'b' | 'c'

(6) ​**Extract<T, U>**​

从类型 T 中提取可以赋值给 U 的类型。

type T = 'a' | 'b' | 'c';
type Extracted = Extract<T, 'a' | 'f'>; // 'a'

(7) ​**Omit<T, K>**​

从类型 T 中删除属性 K(与 Pick 相反)。

type WithoutTimestamp = Omit<IChatMessageParams, 'timestamp'>;
// 等价于:
// type WithoutTimestamp = {
//   chatId: string;
//   content: string;
// };

(8) ​**NonNullable<T>**​

从类型 T 中排除 nullundefined

type T = string | null | undefined;
type NonNullT = NonNullable<T>; // string

(9) ​**Parameters<T>**​

获取函数类型 T 的参数类型元组。

type Fn = (a: string, b: number) => void;
type Params = Parameters<Fn>; // [string, number]

(10) ​**ReturnType<T>**​

获取函数类型 T 的返回值类型。

type Fn = () => IChatMessageParams;
type Return = ReturnType<Fn>; // IChatMessageParams

(11) ​**ConstructorParameters<T>**​

获取构造函数类型的参数类型元组。

class Message {
  constructor(public id: string, public content: string) {}
}
type Params = ConstructorParameters<typeof Message>; // [string, string]

(12) ​**InstanceType<T>**​

获取构造函数类型的实例类型。

class Message { /* ... */ }
type Instance = InstanceType<typeof Message>; // Message

(13) ​**ThisParameterType<T>**​

提取函数类型 Tthis 参数类型。

function fn(this: { name: string }) {}
type ThisType = ThisParameterType<typeof fn>; // { name: string }

(14) ​**OmitThisParameter<T>**​

移除函数类型 Tthis 参数。

function fn(this: { name: string }, age: number) {}
type NoThisFn = OmitThisParameter<typeof fn>; // (age: number) => void

(15) ​**Awaited<T>**​ (TypeScript 4.5+)

获取 Promise 的解析值类型。

type P = Promise<IChatMessageParams>;
type Resolved = Awaited<P>; // IChatMessageParams

3. 工具类型组合使用示例

示例 1:创建部分更新类型

type MessageUpdate = Partial<Pick<IChatMessageParams, 'content' | 'timestamp'>>;
// 允许只更新 content 或 timestamp,且都是可选的

示例 2:安全函数参数

type SafeParams = NonNullable<Parameters<typeof fetchMessage>[0]>;
// 确保 fetchMessage 的第一个参数不为 null/undefined

示例 3:响应式对象键

type MessageKeys = keyof Omit<IChatMessageParams, 'timestamp'>;
// 'chatId' | 'content'(排除了 timestamp)

4. 在 Vue 中的常见应用

(1) 组件 Props 类型

const props = defineProps<{
  config: Pick<IChatConfig, 'theme' | 'fontSize'>;
}>();

(2) 组合式函数返回值

function useMessage() {
  const message = ref<IChatMessageParams>();
  return { message };
}

type MessageReturn = ReturnType<typeof useMessage>;
// { message: Ref<IChatMessageParams | undefined> }

(3) 事件参数类型

const emit = defineEmits<{
  (e: 'update', payload: Partial<IChatMessageParams>): void;
}>();

总结

TypeScript 的内置工具类型极大地增强了类型系统的灵活性,特别是在 Vue 3 项目中:

  1. Pick/Omit 适合处理组件 props 的精确类型
  2. Partial/Required 适合表单编辑场景
  3. ReturnType/Parameters 适合封装复杂函数类型
  4. 工具类型可以无限组合,构建出精确的类型约束

掌握这些工具类型可以显著提升 TypeScript 代码的类型安全性和开发效率。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐