Skip to content

TypeScript Item Mapping

Yongku cho edited this page Apr 1, 2021 · 2 revisions
enum KeyEnum {
    A = 'A',
    B = 'B',
}

enum ValueAEnum {
    A1 = 'A1',
    A2 = 'A2',
}

enum ValueBEnum {
    B1 = 'B1',
    B2 = 'B2',
}

interface Base<Key, Value> {
    key: Key;
    value: Value;
}

type ItemA = Base<KeyEnum.A, ValueAEnum[]>
type ItemB = Base<KeyEnum.B, ValueBEnum[]>

interface ItemMap {
    [KeyEnum.A]: ItemA,
    [KeyEnum.B]: ItemB,
}

type Item = ItemMap extends { [key in KeyEnum]: (infer Value)} ? Value : never;

type Create = <
    T extends keyof ItemMap,
    V extends ItemMap[T]['value'],
>(key: T, value: V) => Base<T, V>;

const createItem: Create = (key, value) => ({key, value});

const itemA: Item = createItem(KeyEnum.A, [ValueAEnum.A1]);
const itemB: Item = createItem(KeyEnum.B, [ValueBEnum.B1]);
enum KeyEnum {
    A = 'A',
    B = 'B'
}

enum ValueA {
    A = 'A'
}
enum ValueB {
    B = 'B'
}

interface ItemA {
    key: KeyEnum.A;
    value: ValueA[];
}

interface ItemB {
    key: KeyEnum.B;
    value: ValueB[];
}

type AnyItem = ItemA | ItemB;

type InferWithKey<Key> = AnyItem & {key: Key};
type InferValue<Key> =InferWithKey<Key>['value'];

const A: InferWithKey<KeyEnum.A> = {
    key: KeyEnum.A,
    value: [ValueA.A],
};

const wrongA: InferWithKey<KeyEnum.A> = {
    key: KeyEnum.A,
    value: [ValueB.B], //Error, KeyEnum.A 와 같이 정확하게 타입이 들어가야 추론되는 거 확인
};
Clone this wiki locally