I have a specified object:
config: {
someKey: someString
}
My goal is to generate a tuple type based on that configuration. Here is an example:
function createRouter<
T extends Record<string, string>
>(config: T) {
type Router = {
// How can I access T[K] below? For instance:
// ['someKey', typeof someString]
navigate: [keyof T, T[K]];
};
}
To elaborate further, the reason I need this Router
type is because I am passing it to a function that returns an object of functions whose parameters are based on the original configuration. The returned object looks like this:
{
[P in keyof T]: (...params: Extract<T[P], readonly unknown[]>) => Promise<void>
}
In this case, T
is the type being passed in as Router
. A practical use of this setup would be:
const router = createRouter({
user: 'user/:id'
});
router.navigate('user', { id: '123' });
In the above usage, navigate
, user
, and id
are all automatically determined. The tuple [keyof T, T[K]]
is utilized within the navigate
function, where keyof T
serves as the first parameter and T[K}
as the second (note: I also transform T[K]
to extract the :id
parameter, but that's not relevant for this discussion).
If config
contains multiple keys, the type should still be inferred correctly, as demonstrated below:
const router = createRouter({
user: 'user/:postId',
post: 'post/:postId'
});
router.navigate('user', { userId: '123' }); // no issue
router.navigate('post', { postId: '123' }); // no problem
router.navigate('post', { userId: '123' }); // error
Please note that I'm not seeking guidance on transforming 'user/:userId'
, as I already possess the necessary type conversion. My focus here is solely on having the config
represented in tuple form.