I want to use mapped types define the type of the following type:
Examples:
const k0: Keyed = {}; // ok, empty
const k1: Keyed = { year: 1, month: 2, week: 3 }; // ok
const k2: Keyed = { year: 1 }; // ok, partial
const k3: Keyed = { hour: 1 }; // wrong! hour is not in 'year' | 'month' | 'week'
const k4: Keyed = { year: undefined }; // wrong, I want a number, not an undefined
I tried with the following:
type Keyed = {
[key in 'year' | 'month' | 'week']: number;
};
but const k2: Keyed = { year: 1 } fails with the error Type '{ year: number; }' is missing the following properties from type 'Keyed': month, week
Then I tried with the following to allow Keyed variables that don’t have every key
type Keyed = {
[key in 'year' | 'month' | 'week']?: number;
};
But then the following const d: Keyed = { year: undefined }; is reported ok, with all the correspondent ‘xxx may be undefined` messages
I want to define that the keys of Keyed must be one of 'year' | 'month' | 'week', without neccesarily having all the properties defined, and that the value should be a number (not null nor undefined).
It seems like a really simple case but I can’t fond the way to achieve it.
I noticed that a similar problem arises with explicit properties. If I have:
type T = {
name?: string
}
All these are valid:
const t1: T = {name: 'sas'}
const t2: T = {name: undefined}
const t3: T = {}
I’d like the ‘name’ property to be optional (that is, it can be missing), but if it is present I want it to be a string, not undefined.
for reference: the solution wa to set the exactOptionalPropertyTypes option in the tsconfig.json file
>Solution :
turn on exactOptionalPropertyTypes in your tsconfig.json (you allow {} type, I think it’s ok)