基于扩展的接口类型的代码分支

Code branching based on types of interfaces that extend

我有一些从基础扩展的接口:

enum eItemType { /* … */ }

interface Item {
    someCommonKeyValPairCollection: eItemType;
    type: eItemType;
    weight: number;
    // …
}

interface ItemTypeA extends Item {
    someKeyValPairCollection: eItemType;
}

interface ItemTypeB extends Item {
    someOtherKeyValPairCollection: eItemType;
}

type tItem = Item | ItemTypeA | ItemTypeB

然后我有一个接收项目的方法,但它可能是(非关键字)泛型 ItemItemTypeAItemTypeB,所以我创建了联合输入 tItem。该方法做了一些常见的事情,然后是一些基于 item.type 的特定事情(循环遍历 someKeyValPairCollectionsomeOtherKeyValPairCollection。打字稿吓坏了,抛出六个赋值错误,例如 Property 'someKeyValPairCollection' is missing in type Item(没有狗屎)。

该方法大致如下所示:

processItem(item: tItem): boolean {
    const isValid: boolean = checkValidity(item);
    if (!isValid) return false;

    _.each(someCommonKeyValPairCollection, () => { /* do some common stuff */ });

    // if (typeof item.someKeyValPairCollection !== 'undefined') // tried first, doesn't like
    if (item.type === eItemType.a) processA(item.someKeyValPairCollection);

    return true;
}

应该如何处理 if (item.type === eItemType.a) // do some special stuff

您需要使用有区别的联合。一个联合,其中一个 属性(在本例中为 type)具有特定类型的特定值。您可以阅读有关该主题的更多信息 here

enum eItemType {
    a, b, c
}

interface Item {
    someCommonKeyValPairCollection: eItemType;
    type: eItemType;
    weight: number;
    // …
}
interface ItemTypeA extends Item {
    type: eItemType.a
    someKeyValPairCollection: eItemType;
}

interface ItemTypeB extends Item {
    type: eItemType.b
    someOtherKeyValPairCollection: eItemType;
}

interface ItemTypeOther extends Item {
    type: Exclude<eItemType, eItemType.a | eItemType.b>
}


type tItem = ItemTypeA | ItemTypeB | ItemTypeOther
function processItem(item: tItem): boolean {
    if (item.type === eItemType.a) {
        item.someKeyValPairCollection
    }
    else if (item.type === eItemType.b) {
        item.someOtherKeyValPairCollection
    } else {
        item  // will be ItemTypeOther
    }
    return true;
}

编辑

添加了一个简单的替代方法来捕获其余枚举值,而无需为每个枚举值定义单独的类型或单独列出它们。