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

Typescript extract type of nested object in template type

I have the following type:

type field_<T> =
    {
        value: T;
        error:
            {
                error: boolean;
                message: string;
            }
        visited: boolean;
        validate: (value: T) => boolean;
    }

and a form that contains all the fields:

interface form_model_
{
    firstName: field_<string>;
    lastName: field_<string>;
}

etc..

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

I would like to collect all the value fields in a way similar to:

type value_type<form_model_interface_> = {
    [key_ in keyof form_model_interface_]: ?*?;
}

what would replace the ?*? or is there a better way to go about it?

>Solution :

There is two options.

First one with conditional types:

type field_<T> =
    {
        value: T;
        error:
        {
            error: boolean;
            message: string;
        }
        visited: boolean;
        validate: (value: T) => boolean;
    }

interface form_model_ {
    firstName: field_<string>;
    lastName: field_<string>;
}

type value_type<form_model_interface_> = {
    [key_ in keyof form_model_interface_]: form_model_interface_[key_] extends field_<any> ? form_model_interface_[key_]['value'] : never
}

// type Result = {
//     firstName: string;
//     lastName: string;
// }
type Result = value_type<form_model_>

Playground

Second one with appropriate constraint for form_model_interface_ generic in value_type. Please keep in mind that in this case you need to define form_model_ as a type instead of interface because type is indexed by default

type field_<T> =
    {
        value: T;
        error:
        {
            error: boolean;
            message: string;
        }
        visited: boolean;
        validate: (value: T) => boolean;
    }

type form_model_ = {
    firstName: field_<string>;
    lastName: field_<string>;
}

type value_type<form_model_interface_ extends Record<string, field_<any>>> = {
    [key_ in keyof form_model_interface_]: form_model_interface_[key_]['value']
}

// type Result = {
//     firstName: string;
//     lastName: string;
// }
type Result = value_type<form_model_>

Playground

Be aware, that there is naming convention in typescript. All types should be Capitalized and CamelCased. So field_ should be written as Field.

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