I want to use mapped types to 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
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'
'year' | 'month' | 'week'
'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 find 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
turn on exactOptionalPropertyTypes
in your tsconfig.json
(you allow {}
type, I think it's ok)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.