Можно ли использовать оператор `keyof` на литералах вместо интерфейсов?

#typescript

Вопрос:

У меня есть объектный литерал, такой как следующий (все свойства известны во время компиляции):

 const foo = {
  "hello": "hola"
};
 

Если foo бы это был интерфейс, а не переменная, я мог бы легко сделать что-то вроде

 /** THEORETICAL ONLY - Does not compile! */
function translate(input: keyof foo): string {
  return foo[input];
}
 

Однако выполнение этого с переменной не работает, так как компилятор не может найти интерфейс с именем foo .

Поддерживает ли Typescript keyof операции с объектными литералами, значения которых известны во время компиляции?

Ответ №1:

keyof работает с типами, но foo является значением. Но typeof оператор принимает значение и выдает его тип, поэтому вы можете использовать keyof typeof foo его для этого.

Обратите внимание, что это работает только в том случае, если вы не связали интерфейс с литералом объекта (спасибо radicand).

Комментарии:

1. Вы самый умный человек в мире?

2. Это компилируется, но на самом деле не дает никакой обратной связи по строке, которую я передаю. Я могу положить туда все, что захочу, и он не будет жаловаться.

3. Это колдовство. Спасибо!

4. Обратите внимание, что это работает только в том случае, если вы не связали интерфейс с литералом объекта.

5. Комментарий @radicand кажется очень важным в этом ответе. Возможно, стоит отредактировать.

Ответ №2:

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

 const foo = {
  "hello": "hola"
};

let data: { [key in keyof typeof foo]:number} amp; { name: string, index: number }[] = [] as any;

data.foo = 1;
data[0] = {name:'foo', 1};