Итак, в машинописном тексте я нашел трюк, позволяющий превратить тип объекта в размеченное объединение, сопоставив тип с парой ключ-значение, а затем создав тип, который может быть любым значением на карте, используя тип keyof
. Вот простой пример:
type SourceType =
{
foo: number,
bar: string
};
type MapWithKey<T> = {[P in keyof T]: { key: P, value: T[P] }}
type DescriminatedUnion = MapWithKey<SourceType>[keyof SourceType];
//The DescriminatedUnion now has the following type
DescriminatedUnion ≡ {key:"foo",value:string} | {key:"bar",value:number}
Это очень полезно, если вы хотите указать очень большое размеченное объединение, однако, когда вы пытаетесь сделать эту конструкцию полностью универсальной, вы получаете другой тип.
type MakeDescriminatedUnion<T> = MapWithKey<T>[keyof T];
type DescriminatedUnion = MakeDescriminatedUnion<SourceType>
//The DescriminatedUnion now has the followin type
DescriminatedUnion ≡ {key:"foo"|"bar",value:number|string}
Это должен быть тот же тип, но по какой-то причине это не так. Я попытался просмотреть документацию по машинописному тексту, чтобы найти причину такого поведения, но не смог. Кто-нибудь знает причину этой разницы? Или, что еще лучше, кто-нибудь знает способ обойти это поведение и сделать его полностью универсальным?