type A = { name?: string };
type B = { name: string | undefined };
const a: A = {}; // ok
const b: B = {}; // error: name is missing
const b2: B = { name: undefined }; // ok
With name?: string, you may leave the property out. With name: string | undefined, you must write the property, even if its value is undefined.
With name?: string, reading the property gives string | undefined.
With name: string | undefined, the key is required. This is useful when you want callers to choose a value on purpose instead of forgetting the field.
The same rule applies to parameters:
f(x?: string)can be called asf().f(x: string | undefined)must be called with an argument.
By default, an optional property also accepts an explicit undefined. The exactOptionalPropertyTypes option changes that. With it on, TypeScript treats a missing key and a key set to undefined as different things.
?means you may leave the key out.| undefinedmeans the key is required, but its value may beundefined.- The same rule applies to function parameters.
exactOptionalPropertyTypesmakes a missing key different from a key set toundefined.
Read more
- Object types (https://www.typescriptlang.org/docs/handbook/2/objects.html)typescriptlang.org
- TSConfig reference (https://www.typescriptlang.org/tsconfig)typescriptlang.org