Jonathan.Brink
Jonathan.Brink

Reputation: 25423

Destructure an object that has the possibility of being undefined as a one-liner in a parameter list

Given an interface MyType:

interface MyType {
  options?: { field0: string, field1: string, field2: string };
}

Mapping over an array, myArray, which has type MyType[], one can destructure the options attribute like this:

myArray.map(({ options }) => {
 const { field0, field1, field2 } = options!;

Note the bang (!), because options could be undefined.

I was trying to turn this into a one-liner, like this:

myArray.map(({ options: { field0, field1, field2 }}) => {

But, this results in errors like "Property 'field0' does not exist on type 'MyType | undefined'" which makes sense because of the way options is typed.

Usually in this scenario I can add the bang operator to bypass the undefined check.

I tried:

myArray.map(({ options: { field0, field1, field2 }!}) => {

and:

myArray.map(({ options!: { field0, field1, field2 }}) => {

...but neither attempts are syntactically valid.

Is there a way to destructure an object that has the possibility of being undefined as a one-liner in a parameter list?

Upvotes: 0

Views: 36

Answers (1)

Bergi
Bergi

Reputation: 665276

If you are sure that the array contains only objects with options, you can use a type assertion on the array itself:

(myArray as Required<MyType>[]).map(({ options: { field0, field1, field2 }}) => {

An alternative that lets you use the non-null assertion is mapping in two steps:

myArray.map(el => el.options!).map({ field0, field1, field2 }) => {

However, the proper safe way to handle this is to anticipate that some array elements actually might have no options, and default those to an empty object:

myArray.map(({ options: { field0, field1, field2 } = {}}) => {

Upvotes: 4

Related Questions