Reputation: 56
Is it possible to tell typescript I don't want to set value type, so it can deduce it later based on scenario, but in the meantime I want to restrict keys?
My approach was to use Record, cause it was really close to reach my goal, but what I really want to do is something like this:
type Lang = 'pl' | 'en';
type AllRoutes = Record<Lang, [implicit type]> // would be awesome to do something like this
// some const strings
const plRoutes = {...};
const enRoutes = {...};
export const allRoutes: AllRoutes = {
en: enRoutes,
pl: plRoutes,
};
When I don't add AllRotues type to allRoutes then typescript knows value types very nicely, but i can add as many keys as I want. I should be restricted
type Lang = 'pl' | 'en';
// some const strings
const plRoutes = {...};
const enRoutes = {...};
type AllRoutes = Record<Lang, typeof plRoutes | typeof enRoutes>
export const allRoutes: AllRoutes = {
en: enRoutes,
pl: plRoutes,
};
The above would work, but I was hoping for nicer solution where we are not forced to write typeof xRoute | zRoute.... It would be pitifull on multiple language.
Upvotes: 1
Views: 2628
Reputation: 1177
If I got your question right, I suggest using generics so you can do something like this (note that you still need to tell TS what your type is when you use the AllRoutes type):
type Lang = 'pl' | 'en';
type AllRoutes<T> = Record<Lang, T>
export const allRoutes: AllRoutes<[the type of your routes]> = {
...
};
However, I think it will be much simpler to use an interface or type if you only want to restrict the keys.
type Routes = {
[key in Lang]: [your type here];
};
// or
interface IRoutes {
en: [your type here],
pl: [your type here]
}
Upvotes: 0
Reputation: 54998
You could be using generics :
type Lang = 'pl' | 'en';
type AllRoutes<V> = Record<Lang, V>
// some const strings
const plRoutes = { a: 'a', b: 3 };
const enRoutes = { c: {} };
export const allRoutes: AllRoutes<typeof plRoutes | typeof enRoutes> = {
en: enRoutes,
pl: plRoutes,
};
or if you have a common interface
interface language { a: string, b: number };
const plRoutes: language = { a: 'a', b: 1 };
const enRoutes: language = { a: 'b', b: 2 };
export const allRoutes: AllRoutes<language> = {
en: enRoutes,
pl: plRoutes,
};
Upvotes: 1