Issue
I'm trying to populate an array consisting of tuples
const countries = ['sg', 'my', 'th'];
const platforms = ['ios', 'android'];
const combinationsToQuery = platforms.flatMap((platform) =>
countries.map((cid) => [platform, cid])
); // [["ios", "sg"], ["ios", "my"], ["ios", "th"], ["android", "sg"], ["android", "my"], ["android", "th"]]
Now I'm trying to add some types to them and below is my attempt
type country = 'sg' | 'my' | 'th' | 'uk' | 'us'
type platform = 'ios' | 'android'
const countries: country[] = ['sg', 'my'];
const platforms: platform[] = ['ios', 'android'];
const combinationsToQuery: [platform, country][] = platforms.flatMap((platform) =>
countries.map((cid: country) => [platform, cid])
);
Type '(country | platform)[][]' is not assignable to type '[platform, country][]'. Type '(country | platform)[]' is not assignable to type '[platform, country]'. Target requires 2 element(s) but source may have fewer.(2322)
If I don't specifically define [platform, country][]
, TS will infer combinationsToQuery
to be (country | platform)[][]
, which doesn't sounds right either?
Solution
The problem becomes more obvious if you look at the return type for the .map
callback. If you tweak your original code to:
countries.map((cid: country) => {
const result = [platform, cid];
return result;
})
Above, result
is typed as (country | platform)[]
- not as a tuple containing two elements, but as an array whose (any number of) elements are either platform
or country
. (So, the resulting type of the whole combinationsToQuery
isn't right either.)
You can either assert the type returned by the callback is a tuple:
const combinationsToQuery: [platform, country][] = platforms.flatMap((platform) =>
countries.map((cid) => [platform, cid] as [platform, country])
);
Or declare your arrays as const
and the return value from the callback as const
and let TypeScript infer the rest for you.
const countries = ['sg', 'my'] as const;
const platforms = ['ios', 'android'] as const;
const combinationsToQuery = platforms.flatMap((platform) =>
countries.map((cid) => [platform, cid] as const)
);
Answered By - CertainPerformance
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.