我在TypeScript中实现了类型安全的路由器,并且在推断类型方面遇到了麻烦。
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 });
router1
的推断类型是Router<{root: any, blog: any}>
。
但我希望路由器的类型为Router<{root:{}, blog:{id:string}}>
。
我尝试添加类型参数(请参阅router2
),它按预期工作。
另外我假设tsc@2.7.2无法推断routes
对象的类型,我明确添加了类型(router3
)。它也可以。
有没有办法在不明确添加类型的情况下解决此问题? 至少我想得到合理的解释,为什么TS在这种情况下将值类型视为任何值。