Distinguish "missing" and "undefined" in TypeScript
#33 · 2021-05-04 · TypeScriptCurrently, it is not possible to properly distinguish the undefined
value type from a missing value.
For example, when defining a type for a plain object literal, you can't specify that a certain property may be missing but must not be undefined
when specified.
TypeScript accepts all the following object literal definitions except the annotated line.
type T1 = {foo?: string}
const t1a: T1 = {}
const t1b: T1 = {foo: 'bar'}
const t1c: T1 = {foo: undefined}
type T2 = {foo: string | undefined}
const t2a: T2 = {} // fails: Property 'foo' is missing in type '{}' but required in type 'T2'.
const t2b: T2 = {foo: 'bar'}
const t2c: T2 = {foo: undefined}
That will likely change, though.
There is a PR that adds the new config flag --strictOptionalProperties
to configure that behaviour.
It will also be in the strict config family which means that enabling --strict
will include --strictOptionalProperties
.
If either one of those flags is used, foo?:string
means that the foo
property either is absent or must be a string.
It cannot be defined as undefined
.
Note that this configuration does not have any influence on accessing non-existing properties.
That would still evaluate to undefined
.
// Will fail with --strictOptionalProperties or --strict:
// Types of property 'foo' are incompatible.
// Type 'undefined' is not comparable to type 'string'.
const t1a: T1 = {foo: undefined}
const t1b: T1 = {}
t1b.foo // still works the same and evaluates to `undefined`
The milestone of this PR is currently set to TypeScript 4.4.0. As of now, this version has not yet been released.