Published on

Understanding Partial<T> in TypeScript

Authors
  • avatar
    Name
    hwahyeon
    Twitter

Partial<T> is a utility type provided by TypeScript that makes all properties of a given type T optional (type?). It is useful in situations where only some properties of an object need to be provided, or when properties can be omitted altogether.

Example

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

type PartialUser = Partial<User>
// Result:
// type PartialUser = {
//   id?: number;
//   name?: string;
//   email?: string;
// }

Implementation

Partial<T> is internally defined in TypeScript as follows:

type Partial<T> = {
  [P in keyof T]?: T[P];
};
  • It iterates over all properties of type T using keyof T and sets each property as optional (?).
  • Optional properties mean that the property may or may not exist in an object, and TypeScript will not raise an error if it is omitted.

Points to Note

1.Runtime does not guarantee property existence:

  • Since Partial<T> makes all properties optional, an object can have none of the properties, and TypeScript will not flag it as an error.
  • At runtime, properties may be missing, so you need to check for their existence or assign default values.
if (user.id !== undefined) {
  // Safe to use the property
}

2.Default values are required at runtime:

  • To handle missing properties, you should add logic to set default values at runtime.

Example: Setting Default Values

function initializeUser(user: Partial<User>): User {
  return {
    id: user.id ?? 0, // Use 0 if user.id is null or undefined
    name: user.name ?? 'Anonymous', // Default to "Anonymous"
    email: user.email ?? 'unknown@example.com', // Default email
  }
}
  • ?? Operator: The Nullish Coalescing Operator returns the right-hand value if the left-hand value is null or undefined.

Use Cases

Object update functions

When you need to update only specific properties of an object, Partial<T> is convenient.

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

// Update only specific properties
function updateUser(id: number, updates: Partial<User>) {
  // For example, retrieve the user from the database
  const user = getUserFromDatabase(id)

  // Apply the provided updates
  const updatedUser = {
    ...user, // Retain existing data
    ...updates, // Merge updated data
  }

  saveToDatabase(updatedUser)
}

The updates object is defined as a Partial<User> type, so you can provide only one property, like name or email, or none at all.

updateUser(1, { name: 'Alice' }) // Update only the name
updateUser(2, { email: 'newemail@example.com' }) // Update only the email
updateUser(3, {}) // Do not update any properties

Default initialization:

Useful when initializing objects with only a subset of their properties or when assigning default values.

const user = initializeUser({ name: 'Jane' })
// Result: { id: 0, name: "Jane", email: "unknown@example.com" }