【问题标题】:使用来自另一个对象的值扩展 TypeScript 接口
【发布时间】:2022-01-23 16:50:33
【问题描述】:

我有如下界面:

export interface IFormField {
    /** Field name */
    name: string;

    /** Label to appear on form */
    label?: string;   // this is optional, since hidden fields do not have label

    /** Field type */
    type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list';
}

我想扩展type 的有效值,通过像这样的对象来选择它们:

const arr = {
   'new_type1': 1,
   'new_type2': 2,
   'new_type3': 3,
};

如何将new_type1new_type2new_type3 添加到type 字段的有效名称列表中?

因此,我想要:

type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list' | `new_type1` | `new_type2` | `new_type3`;

另一个完整(不工作)的例子:

const arr: any = {
   'new_type1': 1,
   'new_type2': 2,
   'new_type3': 3,
};

export interface IFormField {
    /** Field name */
    name: string;

    /** Label to appear on form */
    label?: string;   // this is optional, since hidden fields do not have label

    /** Field type */
    type: keyof typeof arr;
}

const f: IFormField = {
    name: 'ciao',
    type: "new_type1"
};

// adding a new key to `arr` at runtime
arr.type4 = 4;

const g: IFormField = {
    name: 'cioa',
    type: 'type4'  // <- valid for IFormField.type ?
}

有可能吗?

谢谢

【问题讨论】:

    标签: typescript


    【解决方案1】:

    很容易构造出想要的类型:

    • 捕获NewFieldTypes 类型的新键
    • 合并旧类型和新类型
    • 最后,替换IFormField中的类型字段
    export interface IFormField {
        /** Field name */
        name: string;
    
        /** Label to appear on form */
        label?: string;   // this is optional, since hidden fields do not have label
    
        /** Field type */
        type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list';
    }
    
    const arr = {
       'new_type1': 1,
       'new_type2': 2,
       'new_type3': 3,
    };
    
    type NewFieldTypes = keyof typeof arr;
    type ExpandedFieldTypes = IFormField['type'] | NewFieldTypes
    
    type ExpandedIFormField = Omit<IFormField, "type"> & {
      type: ExpandedFieldTypes
    };
    

    Playground

    【讨论】:

    • 谢谢,我已经更新了问题,因为我的起始 arr 不是类型,而是键/值对象,我需要在运行时更改其值,但在编码时进行类型检查。
    • 编译器无法知道您在运行时添加到数组中的内容(可能是用户提供的输入),因此无法强制执行。你能做的最好的就是允许任何字符串。
    【解决方案2】:
    猜你喜欢
    • 2018-12-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    相关资源
    最近更新 更多