'Omit undefined values when creating object literal

Say the interface has an optional property:

interface Foo {
  foo: string;
  bar: string|undefined;
}

We have a value that might be undefined:

makeFoo(bar: string|undefined) {
   const foo = '123';
   return { foo, bar }; // but omit "bar" property if bar === undefined
}

Is it possible for creating the object literal to automatically omit properties with undefined values?



Solution 1:[1]

The best hack I've found for this type of situation so far is leveraging the ... object spread syntax

function makeFoo(bar: string | undefined) {
  const foo = "123";
  return { foo, ...(bar && { bar }) };
}

Here's a Typescript Playground Link where you can give it a go. Admittedly, for more than two properties like this you may be better served by building the object from a collection of key/value pairs like Object.fromEntries and then filtering it.

Solution 2:[2]

This is partially a JavaScript question

interface Foo {
  foo: string;
  bar?: string;
}

function makeFoo(bar?: string): Foo {
   const foo = '123';
   if(typeof bar !== 'string') {
     return { foo };
   }
   return { foo, bar };
}

The problem is that TypeScript cannot omit bar, since bar is omitted on run-time, you could return bar as undefined, but then a problem arises when you use Object.keys(makeFoo()), because then the bar key will appear as a key, so you need to make sure you return an object on run-time that doesn't have bar at all

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Johannes Rudolph
Solution 2 Pavlo