Skip to content
 

TypeScript 中的 Partial 类型详解

更新: 10/13/2025字数: 0 字 时长: 0 分钟

PartialTypeScript 内置的一个实用工具类型(Utility Type),它可以将某个类型的所有属性变为可选的。这在处理对象的部分更新、默认值设置等场景中非常有用。

一、基本语法

typescript
Partial<Type>;

Partial 会接收一个类型 Type,并返回一个新类型,这个新类型包含了 Type 的所有属性,但每个属性都变成了可选的(即添加了 ? 修饰符)。

二、基本示例

1. 基本使用

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

type PartialUser = Partial<User>;
/* 等同于:
type PartialUser = {
  id?: number;
  name?: string;
  age?: number;
  email?: string;
}
*/

const updateData: PartialUser = {
  name: "Alice", // 只需要更新部分属性
  age: 25
};

2. 与对象字面量一起使用

typescript
const defaultConfig = {
  timeout: 1000,
  retry: 3,
  baseUrl: "https://api.example.com"
};

type ConfigOptions = Partial<typeof defaultConfig>;
/* 等同于:
type ConfigOptions = {
  timeout?: number;
  retry?: number;
  baseUrl?: string;
}
*/

三、实际应用场景

1. 对象部分更新

typescript
function updateUser(id: number, changes: Partial<User>) {
  // 只更新传入的属性
  const user = getUser(id);
  return { ...user, ...changes };
}

updateUser(1, { name: "Alice" }); // 只更新name
updateUser(2, { age: 30, email: "new@example.com" }); // 更新多个属性

2. 配置默认值

typescript
interface AppConfig {
  theme: string;
  fontSize: number;
  darkMode: boolean;
}

function createAppConfig(config: Partial<AppConfig> = {}): AppConfig {
  const defaults: AppConfig = {
    theme: "light",
    fontSize: 14,
    darkMode: false
  };

  return { ...defaults, ...config };
}

createAppConfig(); // 使用全部默认值
createAppConfig({ theme: "dark" }); // 只覆盖theme

3. 表单初始值

typescript
interface RegistrationForm {
  username: string;
  password: string;
  email: string;
  agreeTerms: boolean;
}

function initializeForm(values: Partial<RegistrationForm> = {}) {
  return {
    username: "",
    password: "",
    email: "",
    agreeTerms: false,
    ...values
  };
}

四、高级用法

1. 与 PickOmit 结合使用

typescript
interface Product {
  id: number;
  name: string;
  price: number;
  category: string;
  stock: number;
}

// 只允许更新name和price
type UpdateProductDto = Partial<Pick<Product, "name" | "price">>;

// 不允许更新id
type SafeUpdateProductDto = Partial<Omit<Product, "id">>;

2. 嵌套 Partial

typescript
interface Company {
  name: string;
  address: {
    street: string;
    city: string;
    zip: string;
  };
  employees: number;
}

// 浅层Partial
type ShallowPartialCompany = Partial<Company>;
/* address仍然是必填的:
{
  name?: string;
  address: {
    street: string;
    city: string;
    zip: string;
  };
  employees?: number;
}
*/

// 深层Partial
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

type FullPartialCompany = DeepPartial<Company>;
/* 所有层级都变为可选:
{
  name?: string;
  address?: {
    street?: string;
    city?: string;
    zip?: string;
  };
  employees?: number;
}
*/

3. 与 Required 对立使用

typescript
interface Options {
  a?: number;
  b?: string;
  c?: boolean;
}

type RequiredOptions = Required<Options>;
/* 所有属性变为必填:
{
  a: number;
  b: string;
  c: boolean;
}
*/

五、注意事项

  1. strictNullChecks:启用 strictNullChecks 时,可选属性可以显式设置为 undefined

    typescript
    const user: Partial<User> = {
      name: undefined // 允许
    };
  2. 不是递归的Partial 只作用于第一层属性,不会递归应用到嵌套对象

  3. 性能考虑:对非常大的类型使用 Partial 可能会影响编译器性能

  4. 与类的关系Partial 不能用于去除类方法的必填性

我见青山多妩媚,料青山见我应如是。