Определить тип объекта TypeScript, ключи которого являются константами

Мой вопрос похож на Определить интерфейс Typescript с использованием имен констант в качестве ключей, но немного отличается.

Я начинаю с объекта того же типа, ключи которого являются константами.

const KEYS = {
  KEY1: 'hello',
  KEY2: 'world'
} as const;

Но вместо строк у меня есть объекты в качестве значений. Итак, в моем коде я хочу знать, какой тип объекта находится в этом ключе. (Все типы объектов одинаковы.) Например, мне действительно нужно что-то вроде:

const KEYS : {const: string} {
  KEY1: 'hello',
  KEY2: 'world'
} as const;

Есть ли способ сделать это? Я продолжаю получать ошибку ts2353, потому что константа отображается неправильно. Если возможно, мне бы хотелось однострочное решение (то есть, на что мне нужно заменить const: string, чтобы это заработало), потому что у меня почти 200 ключей, поэтому я бы предпочел не переписывать каждую константу отдельно как тип.

Судя по jcalz, похоже, мне нужно что-то вроде «индексной подписи»? Я попробовал несколько разных типов, и, похоже, ничего не помогло, поэтому я не уверен, что делаю неправильно.

Вы просто ищете индексную подпись в форме {[k: string]: string}, как показано в этой ссылке на игровую площадку? Если да, то я напишу ответ (или найду объект для обмана); если нет, то что мне не хватает?

jcalz 30.03.2024 13:46

Да, это именно то, что я ищу. Кажется, все, что я пытаюсь сделать, не работают, поэтому я не уверен, что делаю неправильно.

Aram Papazian 30.03.2024 14:59
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
2
120
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, вам нужна индексная подпись , поскольку «вы не знаете заранее всех названий свойств типа, но знаете форму значений». Вместо {const: string} вы ищете {[k: string]: string}, что означает «каждое свойство с ключом k типа string будет иметь значение типа string». Вы также можете записать это как Record<string, string>, используя тип утилиты Record.

Учитывая, что вы используете утверждение const , вы, вероятно, не хотите, чтобы компилятор фактически забыл об известных ключах KEY1 и KEY2 или литеральных типах "hello" и "world". Итак, хотя вы могли бы написать

const KEYS: { [k: string]: string } = {
  KEY1: 'hello',
  KEY2: 'world'
} as const;

и аннотируйте KEYS как наличие этого типа индексной подписи, это не то, что вам нужно. Вместо этого похоже, что вы просто хотите убедиться, что KEYS удовлетворяет этому типу подписи индекса, не расширяя его до этого типа. Если да, то вы можете использовать оператор удовлетворения:

const KEYS = {
  KEY1: 'hello',
  KEY2: 'world'
} as const satisfies { [k: string]: string };

Это компилируется без изменения выведенного типа KEYS, но все равно выявит ошибку, если вы по ошибке присвоите одному из свойств неправильное значение:

const KEYS = {
  KEY1: 'hello',
  KEY2: 123 // error!
  //~~ <-- Type 'number' is not assignable to type 'string'.
} as const satisfies { [k: string]: string };

Детская площадка, ссылка на код

Другие вопросы по теме