I want to disallow any explicit undefined
value while still allowing implicit undefined
values.
In JavaScript, we have this behavior where accessing a key that does not exist yields undefined
, while accessing a key that does exist can also yield undefined
.
For example,
[1, 2, undefined, 4][2]
-> undefined
[1, 2, 3, 4][99]
-> undefined
{a: 1, b: undefined}.b
-> undefined
{a: 1, b: 2}.foo
-> undefined
.Examples 1 and 3 are accessing values that are explicitly undefined
, whereas examples 2 and 4 are accessing implicitly undefined
values.
What I want to do is specify a key that may or may not exist (optional), but if it DOES exist, it CANNOT be undefined
. Is this possible?
// - mustExistAndCouldBeUndefined MUST exist in this type, but it could be undefined.
// - couldExistAndCouldBeUndefined COULD exist in this type. If it does, it could
// be undefined. If it doesn't, it's undefined.
// - couldExistButCannotBeUndefinedIfItDoes COULD exist in this type. If it does,
// it CANNOT be undefined. If it doesn't, it's undefined.
type Example = {
mustExistAndCouldBeUndefined: number | undefined;
couldExistAndCouldBeUndefined?: number;
??? couldExistButCannotBeUndefinedIfItDoes ???
};
// I want this to be legal, since couldExistButCannotBeUndefinedIfItDoes is allowed
// to not exist (implicitly undefined).
const a: Example = {
mustExistAndCouldBeUndefined: undefined,
};
// I want this to be ILLEGAL since couldExistButCannotBeUndefinedIfItDoes is not
// allowed to both exist and be undefined (explicitly undefined).
const b: Example = {
mustExistAndCouldBeUndefined: undefined,
couldExistButCannotBeUndefinedIfItDoes: undefined,
};
Is it possible to create something that behaves like couldExistButCannotBeUndefinedIfItDoes
in the code block above?
You can enable the Typescript rule exactOptionalPropertyTypes
(Docs) in the tsconfig.json
to allow the ts to differentiate between undefined
and optional.
Without the rule:
type TypeForTest = {
optionalAndUndefined?: string;
}
This will make the optionalAndUndefined
undefined if it does not exist and if it's undefined
by value.
So this will be allowed:
const x:TypeForTest = {}
// OR
const x:TypeForTest = {
optionalAndUndefined: undefined;
}
But after the rule is enabled, it will allow only:
const x:TypeForTest = {}
but this will not be allowed:
const x:TypeForTest = {
optionalAndUndefined: undefined;
}
On the other hand, if you have the following type:
type TypeForTest = {
optionalAndUndefined: string | undefined;
}
this will now be allowed:
const x:TypeForTest = {}
but this is ok:
const x:TypeForTest = {
optionalAndUndefined: undefined;
}