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

In typescript Can I map a type to have ? on property when its corresponding value satisfies a certain condition?

For example, given an object:

const TypeDef1 = {
    foo: {optional: true, type: 'string'},
    bar: {type: 'number'}
}

which conforms to type, say

type TypeDef = {
    [key: string]: {
        optional?: boolean,
        type: 'number' | 'string' | 'boolean'
    }
}

I want to have some reusable typing Transform<T extends TypeDef> such that

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

Transform<typeof TypeDef1>

gives:

{
    foo?: string
    bar: number
}

Is this at all possible in Typescript?

>Solution :

You can use a combination of mapped and conditional types to transform the type definition to an actual type (provided we also use an as const assertion on the definition to make sure we preserve all type info.


type TypeDef =  { [key: string]: { optional?: boolean, type: 'number' | 'string' | 'boolean' } };
type TypeNameToType = {
    number: number,
    string: string,
    boolean: boolean
}
type TypeDefToType<T extends TypeDef> = {
    // The optional properties
    -readonly [P in keyof T as T[P]['optional'] extends true ? P: never]?: TypeNameToType[T[P]['type']]
} & {
    // The mandatory properties
    -readonly [P in keyof T as T[P]['optional'] extends true ? never: P]: TypeNameToType[T[P]['type']]
}

const TypeDef1 = {
    foo: {optional: true, type: 'string'},
    bar: {type: 'number'}
} as const


type X = TypeDefToType<typeof TypeDef1>
//   ^?
// type X = {
//     foo?: string | undefined;
// } & {
//     bar: number;
// }

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