Типы объединяемых объектов объединяются при использовании резервного - PullRequest
1 голос
/ 16 апреля 2020

Я определяю массив, который должен принимать типы 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 глаз.

...