Я определяю массив, который должен принимать типы string
и object
. Типы object
должны содержать два свойства: name
и value
. value
должен быть другим объектом, содержащим произвольный набор key: value
пар.
Я пытаюсь определить некоторые из типов object
, используя различаемое объединение, чтобы свойства value
для некоторые конкретные c name
известны. Однако всегда должен оставаться запасной вариант, так что, когда name
не является известным строковым литералом, value
может быть любым произвольным набором.
Вот то, с чем я работаю до сих пор:
interface IFallbackDef {
name: string;
value: object;
}
type ValueDef<TName extends string = string, TOptions extends object = {}> = {
name: TName;
value: TOptions;
};
type Merged<TValueDef extends ValueDef> = (string | TValueDef | IFallbackDef)[];
interface ITest1Options {
foo: string;
bar: string;
}
interface ITest2Options {
baz: string;
qux: string;
}
const test: Merged<
| ValueDef<'test1', ITest1Options>
| ValueDef<'test2', ITest2Options>
> = [
'asdf',
{
name: 'test1',
value: {
foo: 'asdjfkl',
bar: 'asdf',
/**
* Intellisense shows both sets of properties,
* and typescript allows them all, too
*/
qux: 'asdfkljsdg' // This should be an error
}
},
{
name: 'test2',
value: {
baz: 'blah',
qux: 'test',
/**
* Intellisense shows both sets of properties,
* and typescript allows them all, too
*/
foo: 'salfdj' // This should be an error
}
},
{
name: 'asdf',
value: {
/**
* Intellisense shows both sets of properties,
* should show none.
*/
},
},
]
Проблема, с которой я столкнулся, заключается в том, что когда я включаю IFallbackDef
в объединение, все типы для различных свойств value
объединяются. Если я исключу IFallbackDef
, объединение будет работать правильно, но последний индекс массива test
будет ошибкой, поскольку name: 'asdf'
неизвестно.
Я предполагаю, что, поскольку IFallbackDef
использует базовые типы и форма такая же как IValueDef
, это слияние типов ...? В данный момент я немного растерялся из-за того, как заставить эту работу работать правильно. Очень понравился бы набор sh глаз.