简体   繁体   English

Typescript 模板类型中嵌套 object 的提取类型

[英]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.. ETC..

I would like to collect all the value fields in a way similar to:我想以类似于以下方式收集所有value字段:

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?或者有没有更好的方法来 go 关于它?

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 .第二个对value_type中的form_model_interface_ generic 有适当的约束。 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请记住,在这种情况下,您需要将form_model_定义为type而不是interface ,因为默认情况下type 是索引的

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.请注意,typescript 中有命名约定。 All types should be Capitalized and CamelCased.所有类型都应该大写和驼峰式。 So field_ should be written as Field .所以field_应该写成Field

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM