Reputation: 189
I implements type-safe router in TypeScript and have a trouble with inferring types.
export interface Route<Args> {
match(path: string): Args | void;
build(args: Args): string;
}
export type Routes<State> = {[Tag in keyof State]: Route<State[Tag]>};
export interface Router<State> {
match(path: string): Partial<State> | void;
build(state: Partial<State>): string;
}
export function createRouter<State>(routes: Routes<State>): Router<State> {
/* ... */ return {} as any;
}
const root: Route<{}> = {
match: (path) => /* ... */ undefined,
build: () => '/'
};
const blog: Route<{ id: string }> = {
match: (path) => /* ... */ undefined,
build: ({ id }) => '/blog/' + id
};
const router1 = createRouter({ root, blog });
const router2 = createRouter<{ root: {}, blog: { id: string } }>({ root, blog });
const router3 = createRouter(<Routes<{ root: {}, blog: { id: string } }>>{ root, blog });
The inferred type of router1
is a Router<{root: any, blog: any}>
.
But I expected the router would have a type Router<{root:{}, blog:{id:string}}>
.
I tried to add type parameter (see router2
) and it works as expected.
Also I assumed that [email protected] cannot infer type of routes
object and I added type explicitly (the router3
). It also works right.
Are there any ways to solve this issue without adding types explicitly? At least I would like to get reasonable explanation why TS treat value types as any in this case.
Upvotes: 2
Views: 198
Reputation: 250056
This issue is fixed in Typescript 2.8. It might be related to this issue
Upvotes: 2