Создание интерфейса путем извлечения типов из интерфейса

#typescript

#typescript

Вопрос:

У меня есть следующий интерфейс:

 interface FooBar {
    foo: string;
    bar: number; 
}
  

Есть ли способ динамически создавать тип, который принимает ‘foo’ или ‘bar’?

Нравится:

 
const update = (obj: FooBar, key: string, value: string | number) => {
   ...
}
  

В этом случае, вместо string | number , я хотел бы извлечь значения из FooBar , чтобы мне не приходилось обновлять два места одновременно

Есть идеи? Пока спасибо

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

1. keyof Foobar возвращает тип объединения 'foo' | 'bar' .

2. Поскольку вы спросили, как получить объединение значений, ответ: введите FooBarValues = FooBar[keyof FooBar] . Но это не то, что вы на самом деле хотите использовать здесь. Вы хотите следовать ответу @ccarton, который гарантирует, что значение является правильным типом для предоставленного ключа, а не только типом для любого ключа.

Ответ №1:

Вы можете сделать тип ключа универсальным параметром, а затем индексировать интерфейс:

 function update<K extends keyof FooBar> (obj: FooBar, key: K, value: FooBar[K]) {
  obj[key] = value
}

update(obj, 'bar', 10) // OK
update(obj, 'foo', 'x') // OK

update(obj, 'foo', 10) // Error
// --------------> ~~ 
// Argument of type 'number' is not assignable to parameter of type 'string'.
  

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

1. Спасибо, чувак … это именно то, что я ищу