Reputation: 744
Here is the function in question:
const getCountryLangCode = (countryCode: string) => {
const filtered = Object.entries(config.languages)
.map(([key, language]) => {
if (language.code.split('-')[1] === countryCode) {
return language.code
}
})
.filter(item => item)
const langCode = filtered[0]
return langCode
}
The problem is that 'language' within the map() function is type = unknown, and when I try to build my React app it is failing to build due to this type Object is of type 'unknown'. TS2571
I've tried every version of the typing syntax that I can think of to feed 'any' type to 'language' but I'm doing it wrong.
What's the proper way to declare that language should be type == any ?
Upvotes: 1
Views: 3805
Reputation: 42208
You always want to declare the type higher-up in the chain when you can. You are asking to "declare the type of this variable within map()
" but you want to declare the type of the config
variable. Having a proper type on the config.languages
object will allow Typescript to infer the types of Object.entries
, .map()
, and .filter()
on its own.
config
is an object
with a property languages
. That languages
property is an object
where each value is an object
with a property code
which is a string
. We use the Typescript type Record<Keys, Values>
when we have an object where all values are the same type.
interface MyConfig {
languages: Record<string, {code: string}>
}
There may be other properties that you want to include to help out other functions, but that's all we need to know here.
As pointed out by @Andreas, .map()
is not the ideal function here. If you wanted to find all matches you would use .filter()
directly on the entries. Since you only want to first you should use .find()
. You don't look at the key
at all so you can use Object.values
instead of Object.entries
.
const match = Object.values(config.languages).find(
language => language.code.split('-')[1] === countryCode
);
return match?.code;
If config
has type MyConfig
then the variable languages
in the find()
callback will automatically get the type { code: string }
because Typescript knows the value type of the config.languages
object.
We use the optional chaining ?.
because find
is not guaranteed to find a match, so match
might be undefined
. Our function returns string | undefined
.
Upvotes: 1
Reputation: 1194
To answer your question to put type on Object.entries
you do it like this
...
const filtered = Object.entries<{ code: string }>(config.languages)
.map(([key, language]) => {
...
see there <YourType>
before ( and after entries
. This way you will put specific type on incoming entries
parameter, in your case config.languages
Upvotes: 1