Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: What's the difference between an optional field and a union with undefined?

Tags:

typescript

I want to define an interface with optional fields. I thought the following were synonymous.

(A):

interface State {   userDetails: undefined | string | DataStructure | Error; } 

(B):

interface State {   userDetails?: string | DataStructure | Error; } 

But when I go to initialise the state, (A) forces me to explicitly set the field as undefined, like so:

static readonly initialAppState: AppState = {   userDetails: undefined }; 

But with (B) I can just omit the field completely:

static readonly initialAppState: AppState = { }; 

If I try to omit the field when using definition (A) Typescript will complain saying:

Property 'userDetails' is missing in type 

Why do I have to set the field explicitly when using definition (A)? What's the difference between the two definitions that forces this different requirement when initialising?

Typesript version: 2.3.4


Edit: If you found this question and the answer below interesting or relevant, you may want to know that TypeScript is changing in v4.4 to add the --exactOptionalPropertyTypes flag. This new flag will now cause an error on some of the original code that prompted me to ask this question.

like image 466
Shorn Avatar asked Sep 25 '17 03:09

Shorn


1 Answers

Even at runtime there is a difference between a key with an undefined value and a key that doesn't exist. That TypeScript allows differentiating is not surprising.

Try this:

Object.keys({a: undefined}); 

If leaving a out and setting it's value to be undefined were the same thing then we'd expect the above to return an empty array, but in fact it returns

[ 'a' ] 
like image 124
Samuel Neff Avatar answered Oct 02 '22 18:10

Samuel Neff