Mapped Types
Partial Update Shape
A mapped type can make every property optional for update objects.
optional mapped property
Adding `?` inside a mapped type creates a version where each key may be omitted.
Partial Update Shape
partial_update.ts
Replay: real traced execution (multi-file project)
type Task = {
title: string;
done: boolean;
points: number;
};
type Update<T> = {
[K in keyof T]?: T[K];
};
function applyUpdate(task: Task, update: Update<Task>): string {
const next: Task = { ...task, ...update };
return `${next.title}:${next.done}:${next.points}`;
}
const doneValue: boolean = false;
const original: Task = { title: "Trace", done: false, points: 3 };
const update: Update<Task> = { done: doneValue, points: 5 };
console.log(applyUpdate(original, update));
type Task = {
title: string;
done: boolean;
points: number;
};
type Update<T> = {
[K in keyof T]?: T[K];
};
function applyUpdate(task: Task, update: Update<Task>): string {
const next: Task = { ...task, ...update };
return `${next.title}:${next.done}:${next.points}`;
}
const doneValue: boolean = true;
const original: Task = { title: "Trace", done: false, points: 3 };
const update: Update<Task> = { done: doneValue, points: 5 };
console.log(applyUpdate(original, update));
doneValue ← false, original ← [object Object], update ← [object Object]
13 return `${next.title}:${next.done}:${next.points}`;14}1516const doneValue→ false: boolean = false; //@doneValue=true17const original→ [object Object]: Task = { title: "Trace", done: false, points: 3 };18const update→ [object Object]: Update<Task> = { done: doneValuefalse, points: 5 };1920console.log(applyUpdate(original[object Object], update[object Object]));next ← [object Object]
8 [K in keyof T]?: T[K];9};1011function applyUpdate(task[object Object]: Task, update[object Object]: Update<Task>): string {12 const next→ [object Object]: Task = { ...task[object Object], ...update[object Object] };13 return `${next.titleTrace}:${next.donefalse}:${next.points5}`;14}console.log(applyUpdate(original, update));
17const original: Task = { title: "Trace", done: false, points: 3 };18const update: Update<Task> = { done: doneValue, points: 5 };1920console.log(applyUpdate(original[object Object], update[object Object]));outputTrace:false:5
doneValue ← true, original ← [object Object], update ← [object Object]
13 return `${next.title}:${next.done}:${next.points}`;14}1516const doneValue→ true: boolean = true;17const original→ [object Object]: Task = { title: "Trace", done: false, points: 3 };18const update→ [object Object]: Update<Task> = { done: doneValuetrue, points: 5 };1920console.log(applyUpdate(original[object Object], update[object Object]));next ← [object Object]
8 [K in keyof T]?: T[K];9};1011function applyUpdate(task[object Object]: Task, update[object Object]: Update<Task>): string {12 const next→ [object Object]: Task = { ...task[object Object], ...update[object Object] };13 return `${next.titleTrace}:${next.donetrue}:${next.points5}`;14}console.log(applyUpdate(original, update));
17const original: Task = { title: "Trace", done: false, points: 3 };18const update: Update<Task> = { done: doneValue, points: 5 };1920console.log(applyUpdate(original[object Object], update[object Object]));outputTrace:true:5