Индексировать супертип по ключу подтипа в Typescript

#typescript #typescript-generics

#машинописный текст #typescript-дженерики

Вопрос:

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

 type Foo = { foo: string }
type Bar = { bar: string }
type FooAndBar = Foo amp; Bar 

function fn<T extends Foo | Bar>(list: Array<T>, key: keyof T, acc: FooAndBar) {
    for (const elem of list) {
        acc[key] = elem[key] // ERROR: Type 'keyof T' cannot be used to index type 'FooAndBar'
    }
}


const foos:Foo[] = [{foo: "a"}, {foo: "b"}]
const bars:Bar[] = [{bar: "x"}, {bar: "y"}]

const acc: FooAndBar = { foo: "", bar: "" }
fn(foos, "foo", acc)
fn(bars, "bar", acc)
 

Я сталкиваюсь с ошибкой компиляции Type 'keyof T' cannot be used to index type 'FooAndBar' в строке, прокомментированной выше. Какие ограничения типа я могу добавить, чтобы сделать его проверкой типов?

Ответ №1:

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

В этом случае вы можете сделать fn более общий:

 function fn<T>(list: Array<T>, key: keyof T, acc: T) {
    for (const elem of list) {
        acc[key] = elem[key];
    }
}
 

Таким образом, вы можете передать любой массив, и единственное требование для acc — быть того же типа, что и элементы.

Вот полный пример игровой площадки

Ваш пример кода не может работать, потому что ваш key параметр имеет тип keyof (Foo | Bar) is never : т.е. Foo и Bar не имеет общих ключей