Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to define an object with optional props from an union type in TypeScript

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    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)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading