【问题标题】:Javascript Conditional Inside TypeScript InterfaceTypeScript 接口内的 Javascript 条件
【发布时间】:2017-10-27 22:50:08
【问题描述】:

是否可以在 TypeScript 的接口声明中包含条件。我正在寻找一种方式来表示,基于第一个键的值,第二个键可以是这些值。

示例(不起作用):

interface getSublistValue {

    /** The internal ID of the sublist. */
    sublistId: 'item' | 'partners';

    /** The internal ID of a sublist field. */
    if (this.sublistId === 'item') {
        fieldId: 'itemname' | 'quantity';
    }

    if (this.sublistId === 'partners') {
        fieldId: 'partnername' | 'location';
    }
}

【问题讨论】:

    标签: javascript typescript


    【解决方案1】:

    不,没有。最好的办法是创建单独的接口来描述两种不同类型的数据。

    例如:

    interface SublistItem {
        sublistId: 'item';
        fieldId: 'itemname' | 'quantity';
    }
    
    interface SublistPartners {
        sublistId: 'partners';
        fieldId: 'partnername' | 'location';
    }
    
    function getData(): SublistItem | SublistPartners {
        return (Math.random() < 0.5)
            ? { sublistId: 'item', fieldId: 'itemname' }
            : { sublistId: 'partners', fieldId: 'partnername' };
    }
    
    const someValue = getData();
    
    if (someValue.sublistId === "item") {
        // SublistItem in here
    }
    else {
        // SublistPartners in here
    }
    

    【讨论】:

    • 因此,如果我在创建 someValue 对象时使用此方法,我仍然可以通过自动完成获得 fieldId 的所有 4 个选项,但如果 sublistId 和 fieldId 至少它会给我一个警告不匹配(即“项目”和“合作伙伴名称”)。让我感到震惊的是,如果我的someValueconst someValue: SublistItem | SublistPartners = { sublistId: 'partners', fieldId: 'location' };,那么我会收到关于if (someValue.sublistId === 'item') {} 条件的警告,说location 不是itemnamequantity,我已经知道了,我为什么要这样做收到警告了吗?
    • @JonLamb 嗯...显示的错误消息没有帮助。在这种情况下,它知道sublistId 只会是'partners',因此当您检查'item' 时它会抛出错误。如果您将'item' 替换为'partners',那么它将起作用。尝试一个场景,您从某个地方收到一个值,但您不确定数据是什么。我已经更新了示例。
    【解决方案2】:

    如果你想完全分离你的接口,你可以这样做:

    例如。 sublist.model.ts

    interface SublistItem {
        sublistId: 'item';
        fieldId: 'itemname' | 'quantity';
    }
    
    interface SublistPartners {
        sublistId: 'partners';
        fieldId: 'partnername' | 'location';
    }
    
    export type Sublist = SublistItem | SublistPartners;
    

    现在您可以使用 Sublist 类型,它会根据您提供的字段值正确推断它是 SublistPartners 还是 SublistItem 类型。

    【讨论】:

    • 这是我一直在寻找的完美答案,谢谢
    • 非常棒,谢谢兄弟...
    • 谢谢?一看到就觉得很简单!
    【解决方案3】:

    你可以尝试使用条件类型来解决这个问题:

    interface SublistItem {
        sublistId: 'item';
        fieldId: 'itemname' | 'quantity';
    }
    
    interface SublistPartners {
        sublistId: 'partners';
        fieldId: 'partnername' | 'location';
    }
    
    type ConditionalSublist<bIsSublistItem=true> = bIsSublistItem extends true ? SublistItem : SublistPartners;
    
    let sublistItem: ConditionalSublist<true> = {
        fieldId: "itemname",
        sublistId: "item"
    };
    
    let sublistPartner: ConditionalSublist<false> = {
        fieldId: "partnername",
        sublistId: "partners"
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      • 1970-01-01
      相关资源
      最近更新 更多