{
a = 'a',
b = 'b'
}
interface ObjA {
[Keys.a]: number
}
interface ObjB {
[Keys.b]: number
}
function transform(key: Keys): ObjA | ObjB {
return {
[key]: 100
};
}
сложнее, чем кажется. когда значение используется в качестве индекса, тс его оставит "как есть", тольк если это литеральное значение типа string, number или symbol. Если же это что угодно, кроме литеральных значений (например, юнион `"a" | "b"`), тс выведет пересечение этого типа с keyof any (т.е. с string | number | symbol). Любые пересечения литеральных юнионов обобщаются таким образом до ближайшего общего типа, и "a" | "b" становится просто string. т.к. enum-ы это просто синтаксический сахар поверх юнионов из каждого конституэнта энума, то получается хуйня. единственный способ, который я знаю, чтобы это преодолеть, это вот так: function transform(key: Keys): ObjA | ObjB { if (key === Keys.a) { return { [key]: 10 }; } if (key === Keys.b) { return { [key]: 10 }; } throw new Error("oh shit, I'm sorry"); } любые попытки убрать дупликацию натыкаются на то, что обобщенный тип нельзя использовать в индексере, т.к. он сразу же приводится к string, и это все ломает.
Обсуждают сегодня