Интерфейс [ключ в StringEnum], когда не все элементы StringEnum будут существовать как ключи? - PullRequest
0 голосов
/ 04 мая 2018

Рассмотрим следующие примеры данных, представляющих магазины, содержащие списки ожидающих и выполненных идентификаторов заказов на покупку:

{
    "shop-45": {
        "FULFILLED": [55, 70]
    },
    "shop-46: {
        "PENDING": [59, 54]
        "FULFILLED": [100, 101]
    }
}

Если в магазине нет ни ожидающих, ни выполненных заказов, он вообще не появляется в списке.

Я попытался представить это, используя следующее:

type Status = "PENDING" | "FULFILLED";

interface ShopList {
    [shop: string]: {
        [status in Status]: number[];
    }
}

Неудивительно, что tsc жалуется, когда у меня нет обоих PENDING и FULFILLED в качестве суб-свойств магазина.

Я подавил ошибку, сделав это свойство необязательным ([status in Status]?: number[]), но я не думаю, что это действительно то, что я хочу сделать, , так как магазин никогда не будет иметь нулевых подсвойств .

Еще одна причудливая попытка выстрела в темноте [status in Partial<Status>]: number[]; жалуется аналогично.

Это мой единственный вариант, и просто не о чем беспокоиться?

Это тривиальный MCVE; настоящий гораздо сложнее и имеет больше слоев. Это (всегда?) Мотивирует использование обобщений вместо того, чтобы повторять каждое возможное имя ключа: перечисление используется как значения поля в других объектах.

Ссылки на TypeScript / Issues, обсуждающие похожие ситуации: 7374 | 19211 | 14934 | 5683 .

1 Ответ

0 голосов
/ 05 мая 2018

Если вы хотите запретить сценарий, в котором магазин не будет отображаться без PENDING или FULFILLED, вам нужно быть немного более четким с вашими типами. Например, вы можете сделать следующее:

type ShopWithPending = {
    PENDING: number[];
}

type ShopWithFulfilled = {
    FULFILLED: number[];
}

type ShopStatus = ShopWithPending | ShopWithFulfilled | (ShopWithPending & ShopWithFulfilled);

interface ShopList {
    [shop: string]: ShopStatus
}

Однако из-за этого трудно использовать shops, извлеченный из списка, поскольку Typescript увидит тип ShopStatus как что-то, что не гарантированно имеет какие-либо свойства и, следовательно, не позволит вам использовать PENDING или FULFILLED.

Чтобы вернуть эту способность, вам понадобится что-то еще для Shop типов, которые позволяют Typescript сужать вывод типов до конкретной типизированной версии.

...