Item 21: Create Objects All at Once
Prefer to build objects all at once rather than piecemeal.
Use multiple objects and object spread syntax ({...a, ...b}
) to add properties in a type-safe way.
Know how to conditionally add properties to an object.
const pt = { } ;
// ^? const pt: {}
pt . x = 3 ;
// ~ Property 'x' does not exist on type '{}'
pt . y = 4 ;
// ~ Property 'y' does not exist on type '{}'
💻 playground
interface Point { x : number ; y : number ; }
const pt : Point = { } ;
// ~~ Type '{}' is missing the following properties from type 'Point': x, y
pt . x = 3 ;
pt . y = 4 ;
💻 playground
const pt = { } as Point ;
// ^? const pt: Point
pt . x = 3 ;
pt . y = 4 ; // OK
💻 playground
const pt : Point = {
x : 3 ,
y : 4 ,
} ;
💻 playground
const pt = { x : 3 , y : 4 } ;
const id = { name : 'Pythagoras' } ;
const namedPoint = { } ;
Object . assign ( namedPoint , pt , id ) ;
namedPoint . name ;
// ~~~~ Property 'name' does not exist on type '{}'
💻 playground
const namedPoint = { ...pt , ...id } ;
// ^? const namedPoint: { name: string; x: number; y: number; }
namedPoint . name ; // OK
// ^? (property) name: string
💻 playground
const pt0 = { } ;
const pt1 = { ...pt0 , x : 3 } ;
const pt : Point = { ...pt1 , y : 4 } ; // OK
💻 playground
declare let hasMiddle : boolean ;
const firstLast = { first : 'Harry' , last : 'Truman' } ;
const president = { ...firstLast , ...( hasMiddle ? { middle : 'S' } : { } ) } ;
// ^? const president: {
// middle?: string;
// first: string;
// last: string;
// }
// or: const president = {...firstLast, ...(hasMiddle && {middle: 'S'})};
💻 playground
declare let hasDates : boolean ;
const nameTitle = { name : 'Khufu' , title : 'Pharaoh' } ;
const pharaoh = { ...nameTitle , ...( hasDates && { start : - 2589 , end : - 2566 } ) } ;
// ^? const pharaoh: {
// start?: number;
// end?: number;
// name: string;
// title: string;
// }
💻 playground
const { start} = pharaoh ;
// ^? const start: number | undefined
💻 playground