TypeScript отображаемое значение типа в зависимости от ключа - PullRequest
0 голосов
/ 26 февраля 2019

Можно ли ограничить тип значения записи карты в зависимости от ключа элемента?

type Thing<T extends string = any> = {
    type: T
}

type ThingMap<T extends Thing> = {
    [K in T["type"]]: T
}

interface A {
    type: "A",
    foo: boolean,
}

interface B {
    type: "B",
}


// This compiles.
const map: ThingMap<A | B> = {
    A: { type: "A", foo: true },
    B: { type: "B" },
}

// But this also compiles, when it should not.
const map: ThingMap<A | B> = {
    A: { type: "A", foo: true },
    B: { type: "A", foo: true },
}

1 Ответ

0 голосов
/ 26 февраля 2019

Вы хотите убедиться, что для определенного K типом ключа является не весь союз (т. Е. T), а скорее просто член объединения с типом K.Вы можете использовать Extract, чтобы получить члена профсоюза со свойством type типа K:

type Thing<T extends string = any> = {
    type: T
}

type ThingMap<T extends Thing> = {
    [K in T["type"]]:  Extract<T, { type : K }>  // Extract the union member that has { type: K }
}

interface A {
    type: "A",
    foo: boolean,
}

interface B {
    type: "B",
}


// This compiles.
const map: ThingMap<A | B> = {
    A: { type: "A", foo: true },
    B: { type: "B" },
}

// Err now
const map2: ThingMap<A | B> = {
    A: { type: "A", foo: true },
    B: { type: "A", foo: true },
}
...