J
J
Juniorrrrr2021-04-22 10:13:46
typescript
Juniorrrrr, 2021-04-22 10:13:46

How to specify that a function argument is a value from an array?

There is an array of values ​​And there is some function that takes a string, this string can be one of the values ​​of the array.
const arr = ['name', 'age', 'surname'];

// key === 'name' || age' || 'surname'
// obj:ObjType
const prepareFn = (key) => { obj[key] };


TS gives this error:

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'


Please tell me how to type key correctly

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alex, 2021-04-22
@Juniorrrrr

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...

Y
Yuri Gorin, 2021-04-23
@CoolWolf

I think that to be tied on string constants - vicious practice. If only because it is not convenient - there are no hints in the IDE and it is difficult to refactor.
In your case, enum would be perfect:

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);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question