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

Extend an interface with new set of properties based on original interface with mapped types

Supposed I have the following interface:

interface Person {
    name: string;
    age: number;
    location: string;
}

I want to extend it to have 3 additional properties, one for each of the interfaces’ original properties.

So final outcome I want is:

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

interface Person {
    name: string;
    nameHidden: boolean;
    age: number;
    ageHidden: boolean;
    location: string;
    locationHidden: boolean;
}

I was looking into mapped types by TypeScript: https://www.typescriptlang.org/docs/handbook/2/mapped-types.html

But I am unable to figure out how I can achieve this behavior. It only shows examples of how to re-map the existing properties, but not add new ones on top of the existing ones.

>Solution :

You’ve said you don’t need it to be the same interface. If so, you can do this:

type WithFlags<T> = T & {
    [Key in keyof T as Key extends string ? `${Key}Hidden` : never]: boolean;
};

type PersonWithFlags = WithFlags<Person>;

Playground example

That creates a new type that is the passed-in type T plus a property for every property in it (at least the ones whose names extend string) with Hidden added to the name and the type boolean.

Titian Cernicova-Dragomir points out in a comment (thanks!) that we can avoid the conditional in that key mapping by using & string instead, which is a bit shorter:

type WithFlags<T> = T & {
    [Key in keyof T & string as `${Key}Hidden`]: boolean;
// −−−−−−−−−−−−−−−−^^^^^^^^^
};

Playground link

pilchard points out in a comment that the documentation has virtually this same example. They do the remapping like Titian, but in a different place:

type WithFlags<T> = T & {
    [Key in keyof T as `${Key & string}Hidden`]: boolean;
// −−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^
};

Playground link

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