Это может быть как раз ваш тип.

Позвольте мне начать с того, что я люблю TypeScript, он помогает мне выявлять ошибки и делает код более предсказуемым. При этом может быть сложно правильно ввести код. Изучение и интеграция TypeScript может превратиться в поездку на американских горках. Могу с уверенностью сказать, что это мой случай.

Если вы хотите попробовать решить проблему без дополнительных объяснений, вы можете проверить эту ссылку на TypeScript Playground.

Справочная информация
Я создаю «Quickscan», который представляет собой просто форму с большим количеством функций. Чтобы отслеживать глобальные настройки Quickscan, я создал Provider с частью состояния только для чтения. Для обновления объекта состояния мы создаем простую функцию. В отдельности (и в урезанном виде) это выглядит так:

Проблема
Здесь у нас две проблемы. Первая заключается в том, что когда мы вызываем функцию setQuickscanState в строке 22, она не выдает нам ошибку. Почему? потому что значение может быть «логическим, числовым или нулевым» (строка 8), и мы присваиваем ему число. Это также объясняет проблему в строке 19 (см. ошибку TS в комментарии к строке 17). При обновлении объекта-состояния TypeScript не знает, соответствует ли комбинация ключ/значение интерфейсу QuickscanState.

Мы хотим, чтобы TypeScript понимал, что когда ключ равен «showIntros», тип значения является логическим. Когда ключ равен «editId», тип значения является числом или нулевым значением. Или, точнее, когда мы обновляем объект, мы хотим знать тип значения на основе ключа.

Прежде чем мы углубимся в решение, вы можете попробовать решить проблему по этой ссылке на TypeScript Playground.

.

.

Подсказка: Дженерики для победы!

.

.

.

Решение

Это решает все наши проблемы. В строке 11 мы определяем общий ‘K’, который расширяет keyof QuickscanState. В этом случае K — это либо showIntros, либо EditId. Затем мы определяем типы для параметров функции, ключ — просто K, а значение — то, что находится в нашем QuickscanState интерфейсе для этого ключа. Простой, но эффективный и ориентированный на будущее.

Если вы хотите еще немного поиграть с этим:
Ссылка на площадку TypeScript к проблеме
Ссылка на площадку TypeScript на решение

Бонус 1: реальная реализация в Vue.js
Если вам интересно узнать реальную реализацию проекта, вот она:

Бонус 2: мысль о первоначальном решении
Первое, что пришло мне в голову, когда я столкнулся с этой проблемой, — создать два случая, чтобы TypeScript мог форсировать одно или другое, примерно так:

Это уловило ошибку в строке 29, но не устранило ошибку TypeScript в строке 26, потому что устанавливаемое значение по-прежнему может быть «логическим», «числом» или «нулевым». Это потому, что TypeScript объединяет два типа. Это решение также не очень перспективно: когда мы добавляем свойство к нашему объекту, нам также приходится создавать для него тип. Это заставило меня подумать, что решение должно быть более общим, что привело меня к фактическому общему решению.

Я бы хотел увидеть, если бы вы придумали другое решение! Я надеюсь, что вы могли бы терпеть меня в этом, и, пожалуйста, дайте мне знать, если вы хотите увидеть больше реальных проблем. Спасибо за прочтение и приятного вам дня :)

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Присоединяйтесь к нашему сообществу Discord.