Trying out TypeScript for a React project and I\'m stuck on this error:
Element implicitly has an \'any\' type because expression of type \'string\' can\'t b
// bad
const _getKeyValue = (key: string) => (obj: object) => obj[key];
// better
const _getKeyValue_ = (key: string) => (obj: Record) => obj[key];
// best
const getKeyValue = (key: U) => (obj: T) =>
obj[key];
Bad - the reason for the error is the object type is just an empty object by default. Therefore it isn't possible to use a string type to index {}.
Better - the reason the error disappears is because now we are telling the compiler the obj argument will be a collection of string/value (string/any) pairs. However, we are using the any type, so we can do better.
Best - T extends empty object. U extends the keys of T. Therefore U will always exist on T, therefore it can be used as a look up value.
Here is a full example:
I have switched the order of the generics (U extends keyof T now comes before T extends object) to highlight that order of generics is not important and you should select an order that makes the most sense for your function.
const getKeyValue = (key: U) => (obj: T) =>
obj[key];
interface User {
name: string;
age: number;
}
const user: User = {
name: "John Smith",
age: 20
};
const getUserName = getKeyValue("name")(user);
// => 'John Smith'
const getKeyValue = (obj: T, key: K): T[K] => obj[key];