Я думаю, что это способ сделать это:
type Keyed<T extends MyUnion> = {
[P in T["kind"]]: T extends (infer U)
? T["kind"] extends P
? U[] : never
: never
}
но это довольно запутанно. Возможно, более удобочитаемо просто написать класс Keyed
вручную.
Требуются цепные операторы extends
, потому что вы хотите быть уверенными, что в массиве нет разных типов. Например, компилятор предупредит вас об этом, потому что у вас есть типы «A» и «B» в массиве «A»:
var c: Keyed<MyUnion> = {
"A": [{ kind: "A" }, { kind: "B" }], // Error on 2nd item, bacause "B"
"B": [{ kind: "B" }],
"C": []
}
Это действительные данные:
var c: Keyed<MyUnion> = {
"A": [{ kind: "A" }, { kind: "A" }],
"B": [{ kind: "B" }],
"C": []
}
Я переименовал собственность type
в kind
. Он соответствует соглашению в документации TypeScript и позволяет избежать путаницы при использовании ключевого слова type
для имени свойства.