Demonov
@Demonov
Frontend developer

TypeScript. Как собрать объект из массива строк?

Пытаюсь сделать метод который будет принимать массив строк, а на выходе выдавать объект с ключами этих строк, а значения брать из другого объекта.
Конкретно в моём случае:
Нужно передать методу массив строк, которые являются именами стилей
например:
['width', 'fontSize', 'fontStyle', ...]
Метод пробежится по массиву и сформирует объект, я делаю это с помощью reduce.
Я пытался сделать что-то типа того:
getStyles(styles: Array<keyof CSSStyleDeclaration>): Record<keyof CSSStyleDeclaration, string> {
    return styles.reduce((res, style) => {
      res[style] = this.$nativeElement.style[style];
      return res;
    }, {});
  }

Ошибка указывать на res[style] // Element implicitly has an 'any' type because expression of type 'number | "textAlign ...
Также я не правильно указал возвращаемое значение, просто не знаю как сделать правильно.

Как можно это реализовать? Желательно чтобы при вызове метода я знал что он вернёт.

any не использую
  • Вопрос задан
  • 351 просмотр
Решения вопроса 3
Aetae
@Aetae Куратор тега TypeScript
Тлен
На самом деле чтоб была полноценная типизация надо как-то так:
getStyles<T extends keyof CSSStyleDeclaration>(styles: readonly T[]) {
  return styles.reduce((res, style) => {
    res[style] = this.$nativeElement.style[style];
    return res;
  }, {} as Pick<CSSStyleDeclaration, T>);
}

Песочница.

Разница с решением от Дмитрий в том, что тип получившегося объекта будет содержать только полученные ключи, а не все возможные в CSSStyleDeclaration.
Ответ написан
@StockholmSyndrome
getStyles<T extends keyof CSSStyleDeclaration>(styles: Array<T>): Record<T, string> {
    return styles.reduce((res, style) => {
        res[style] = this.$nativeElement.style[style];
        return res;
    }, {} as Record<T, string>);
}

тогда выходной объект будет содержать только те свойства, которые были в styles
Ответ написан
Комментировать
@disappearedstar
Фронтенд-разработчик
getStyles(styles: Array<keyof CSSStyleDeclaration>) {
    return styles.reduce((res, style) => {
        res[style] = this.$nativeElement.style[style];
        return res;
    }, {} as Record<keyof CSSStyleDeclaration, CSSStyleDeclaration[keyof CSSStyleDeclaration]>);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы