Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type dynamic object functions call

Tags:

typescript

I have this code (Playground):

const routes = {
    projects: ({}) => "/projects",
    "projects.edit": ({ id }: { id: string }) => `/projects/${id}`,
    report: ({ projectId }: { projectId: string }) => `/report/${projectId}`,
};

type Routes = typeof routes;

export function generateUrl<Name extends keyof Routes>(
    name: Name,
    params: Parameters<Routes[Name]>[0]
): string {
    const fn = routes[name];
    return fn(params);
}

I get this error in line fn(params). How would I write it to type-check (without using any)?

Property 'id' is missing in type '{ projectId: string; }' but required in type '{ id: string; }'.

like image 866
tokland Avatar asked Oct 15 '22 09:10

tokland


1 Answers

Here is another solution
This allows you to have routes that take multiple parameters.

type Route = (...args: any[]) => string;
type Routes = {
    [index: string]: Route;
};

function createUrlGenerator<T extends Routes>(router: T) {
    return <K extends keyof T>(name: K, ...params: Parameters<T[K]>): string => {
        return router[name].apply(null, params);
    }
}

const routes = {
    projects: ({}) => "/projects",
    "projects.edit": ({ id }: { id: string }) => `/projects/${id}`,
    report: ({ projectId }: { projectId: string }) => `/report/${projectId}`,
    multyParams: (id: number, query: string) => `${id}/${query}`
};

export const generateUrl = createUrlGenerator(routes);

generateUrl('multyParams', 123, '43');
generateUrl('multyParams', 123); // Exception
generateUrl('projects.edit', { id: '123' });
generateUrl('projects.edit', { id: 123 }); // Exception
like image 122
Artem Bozhko Avatar answered Oct 20 '22 22:10

Artem Bozhko