Защита типа TypeScript на основе типа объединения - PullRequest
0 голосов
/ 12 марта 2020

Со следующими типами

export type AnyRecord = ARecord | BRecord | CRecord; // these "XRecord" interfaces are generated by graphql code gen with discriminator field "__typename"
export type RecordType = AnyRecord["__typename"];
export type RecordTypeMapping = {
    [K in RecordType]: Extract<AnyRecord, { __typename: K }>
};
// Record type mapping gives type { "aRecordTypeName": ARecord, "bRecordTypeName": BRecord, etc }

Я пытаюсь получить условие дискриминатора, работающее для следующего типа:

export interface IRecordGroup<T extends RecordType = RecordType> {
    recordType: T;
    records: Array<RecordTypeMapping[T]>;
}

с использованием

interface Props {
    groups: Array<IRecordGroup>; // there's no generic parameter here, so it's the union of all record types.
}

// ...

const groups = props.groups;
groups.map((g) => {
    switch(g.recordType) {
        case "aRecordTypeName":
            // wanted resolved type for g.records: ARecord[]
            // actual resolved type for g.records: (ARecord|BRecord|CRecord)[]
            break;
    }
})

Есть ли способ выполнить это sh без приведения g.records и без использования AnyRecord[] или AnyRecord[][] (внешний массив - это группировка) в качестве реквизита? Я надеюсь избежать ручного создания отдельных типов IRecordGroup для каждого типа записи и последующего создания объединяющего типа только для целей защиты типов. Похоже, что это может быть единственный маршрут, и это ограничение.

...