Juniorrrrr
@Juniorrrrr

Как указать что аргумент функции — это значение из массива?

Есть массив значений
const arr = ['name', 'age', 'surname'];

И есть некоторая функция, которая принимает строку, строка эта может быть одним из значений массива.
// key === 'name' || age' || 'surname'
// obj:ObjType
const prepareFn = (key) => { obj[key] };


TS выдает такую ошибку :

Element implicitly has an 'any' type because expression of type 'string | number | symbol' can't be used to index type 'ObjType'.
No index signature with a parameter of type 'string' was found on type 'ObjType'


Подскажите пожалуйста, как правильно типизировать key
  • Вопрос задан
  • 63 просмотра
Решения вопроса 1
Kozack
@Kozack
Thinking about a11y
const arr = ['name', 'age', 'surname'] as const;
type arrKeys = typeof arr[number]

const obj: {[k in arrKeys]?: any} = {}
const prepareFn = (key: arrKeys) => { obj[key] };



prepareFn('name')
// @ts-expect-error
prepareFn('name2')

obj.name
// @ts-expect-error
obj.name2


https://www.typescriptlang.org/play?#code/MYewdgzg...
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Думаю, что завязываться на строковые константы - порочная практика. Хотя бы потому что не удобно - нет подсказок в IDE и сложно рефакторить.

В вашем случае идеально бы подошёл enum:

enum EField {
  Name = 'name',
  Age = 'age',
  Surname = 'surname',
};

const arr = [EField.Name, EField.Age, EField.Surname];

const obj: {[K in EField]?: any} = {}
const prepareFn = (key: EField) => { obj[key] };

prepareFn(EField.Name);
prepareFn(EField.Age);
Ответ написан
Ваш ответ на вопрос

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

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