Object destructuring in typescript

2.9k Views Asked by At

Is it possible to destructure an object which comes from an function call without Typescript complaining?

File 1

  • React Component 1
...
let obj = null // <-- object initialization
...
useEffect(() => {
  obj = functionCall(...) // <-- function call that populates the object
}, [obj])
  • React component 2
const { key1, key2 } = obj // <-- object destructuring

Here I get the following complain from Typescript

  • Property 'key1' does not exist on type 'null'.
  • Property 'key2' does not exist on type 'null'.

How can I remove those warning?

3

There are 3 best solutions below

0
On BEST ANSWER

Specify a type for obj:

let obj: null | {key1: sometype; key2: sometype; } = null;

Note that since obj may have the value null, you'll need a guard or a default value around that destructuring assignment:

if (obj) {
    const { key1, key2 } = obj;
}

or

const { key1, key2 } = obj ?? {key1: defaultForKey1, key2: defaultForKey2};

or

const { key1 = defaultForKey1, key2 = defaultForKey2 } = obj ?? {};

The difference between the last two is what happens if obj isn't null but key1 or key2 has the value undefined (if it's allowed to by the types).

0
On

useEffect runs after your initial render - so on the first render obj will be null, and so TS is right to complain.

You need to check that obj is not null before de-structuring. Also, give it a type e.g

type MyType = { key1: string; key2: number; }; // for example

let obj: MyType | null  = null;

if (obj) {
  const { key1, key2 } = obj; // OK
} else {
  // In here, obj is null
}

0
On

Non-null assertion operator:

const { key1, key2 } = obj!;