Suggest an editImprove this articleRefine the answer for “Utility type partial in TypeScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Partial<T>`** - a TypeScript utility type that makes every property in T optional at compile time. ```ts type User = { id: number; name: string }; type PartialUser = Partial<User>; // { id?: number; name?: string } function patch(user: User, changes: Partial<User>): User { return { ...user, ...changes }; } ``` **Key point:** only affects the top level. Nested objects still require all their fields if provided.Shown above the full answer for quick recall.Answer (EN)Image**`Partial<T>`** - a built-in TypeScript utility type that takes any object type T and makes every property optional. ## Theory ### TL;DR - Think of it like a draft: fill only the fields you have, skip the rest - `{ name: string }` becomes `{ name?: string }` for every property in T - Use it for PATCH requests, form state, and config objects with optional fields - It only goes one level deep. Nested objects stay required if you provide them - No runtime cost. TypeScript removes it during compilation ### Quick example ```ts type User = { id: number; name: string; email: string; }; // All fields become optional const update: Partial<User> = { name: "Alice" }; // id and email omitted - fine // Merge pattern const fullUser: User = { id: 1, name: "Bob", email: "bob@test.com" }; const updated: User = { ...fullUser, ...update }; // { id: 1, name: "Alice", email: "bob@test.com" } ``` `update` carries only the field you want to change. Spread merges it back into a complete `User`. ### Key difference `Partial<T>` scales with T automatically. Add a field to `User` and every `Partial<User>` in the codebase reflects it without any extra work. That beats maintaining `{ name?: string; email?: string }` by hand and keeping it in sync. ### When to use - PATCH endpoints: send only changed fields to the server - React form state: track which fields the user has touched - Config objects: set defaults and let callers override parts - Reducer updates: merge a partial payload into existing state ### How the compiler handles this TypeScript expands `Partial<T>` as a mapped type: `{ [K in keyof T]?: T[K] }`. The compiler walks every key in T and adds `?`. Nothing ends up in the JavaScript output. V8 and the browser never see it. ### Common mistakes **Mistake 1: assuming Partial works recursively.** ```ts type Nested = { user: { name: string; age: number }; }; const x: Partial<Nested> = { user: { name: "Alice" } }; // Error! age is still required ``` `Partial` only touches the top-level keys. If you provide `user`, its inner shape stays fully required. The nested-object trap catches almost everyone the first time. For deep optionality, write a `DeepPartial`: ```ts type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T; ``` **Mistake 2: forgetting runtime checks for undefined.** ```ts function update(data: Partial<User>) { console.log(data.id.toString()); // Compiles. Crashes if id is missing. } ``` TypeScript does not emit any guards. Add the check yourself: `if (data.id !== undefined)`. **Mistake 3: using Partial when one field must always be present.** If `id` is always required, `Partial<User>` still allows it to be skipped. Combine types instead: ```ts type PatchUser = Pick<User, "id"> & Partial<Omit<User, "id">>; ``` **Mistake 4: applying Partial to a primitive type.** ```ts type ID = number; const x: Partial<ID> = undefined; // Error. Partial<number> is still number. ``` Primitives have no keys. `Partial` has no effect on them. Use `number | undefined` instead. ### Real-world usage - **React** (React Hook Form): `useState<Partial<Profile>>({})` for partial form state - **NestJS**: `Partial<CreateUserDto>` as the body type for PATCH endpoints - **Redux Toolkit**: `Partial<State>` in slice reducers for optional field updates - **Prisma**: `prisma.user.update({ data: partial })` accepts a partial model shape ### Follow-up questions **Q:** What does `Partial<{ a: string; b: number }>` expand to? **A:** `{ a?: string; b?: number }`. Every property gets `?` added. **Q:** Does `Partial` preserve `readonly` modifiers? **A:** No. `Partial<{ readonly x: number }>` drops `readonly`, leaving `{ x?: number }` as writable. **Q:** Any runtime performance impact? **A:** None. Pure compile-time. The JavaScript output is identical with or without `Partial`. **Q:** What is the difference between `Partial<T>` and `{ [K in keyof T]?: T[K] }`? **A:** They are identical. `Partial<T>` is a named alias for that mapped type, defined in TypeScript's `lib.es5.d.ts`. **Q:** (Senior) How would you type a PATCH endpoint where `id` is always required but other fields are optional? **A:** `type PatchUser = Pick<User, 'id'> & Partial<Omit<User, 'id'>>`. This enforces `id` while making everything else optional. ## Examples ### Basic: updating an object with spread ```ts type Point = { x: number; y: number; z?: number }; function move(origin: Point, delta: Partial<Point>): Point { return { ...origin, ...delta }; } const start: Point = { x: 0, y: 0 }; const result = move(start, { x: 10 }); // { x: 10, y: 0 } ``` `delta` carries only the axes to change. `move` merges it with the current position and returns a full `Point`. `z` is already optional in `Point`, so it never causes issues here. ### Intermediate: form state in React ```ts interface Profile { name: string; age: number; bio: string; } function EditProfileForm({ user }: { user: Profile }) { const [draft, setDraft] = useState<Partial<Profile>>({}); const handleSave = () => { const updated: Profile = { ...user, ...draft }; // safe merge saveProfile(updated); }; return ( <input value={draft.name ?? user.name} onChange={(e) => setDraft((d) => ({ ...d, name: e.target.value }))} /> ); } ``` `draft` holds only the fields the user has touched. On save, it merges over the original `user` so no field goes missing. This pattern works well with any form library or plain React state.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.