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

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

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

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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