You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TypeScript的getRoutesForPages返回带前缀的映射类型?

解决TypeScript路由前缀类型生成问题

1. 改造shared.ts的类型与函数

首先新增一个泛型类型来生成带前缀的路由对象类型,然后修改路由生成函数的返回类型,同时修复原函数修改只读对象的问题:

export type ReverseMap<T> = T[keyof T];

// 泛型类型:给原路由对象的每个值添加指定前缀
type PrefixedRoutes<T extends Record<string, string>, Root extends string> = {
  [K in keyof T]: `/${Root}/${T[K]}`;
};

export const getRoutesForPages = <T extends Record<string, string>, const Root extends string>(
  pages: T,
  root: Root
): PrefixedRoutes<T, Root> => {
  // 创建新对象存带前缀的路由,不修改原只读对象
  const prefixedRoutes = {} as PrefixedRoutes<T, Root>;
  
  for (const key in pages) {
    if (pages.hasOwnProperty(key)) {
      prefixedRoutes[key] = `/${root}/${pages[key]}` as const;
    }
  }
  
  return prefixedRoutes;
};

2. 调整admin.ts的调用逻辑

不需要手动指定泛型,TypeScript会自动推导正确的类型:

import { getRoutesForPages, ReverseMap } from './shared';

const ROOT = 'admin';

export const PAGES = {
  PAGE_1: `p-1`,
  PAGE_2: `p-2`,
} as const;
export type Page = ReverseMap<typeof PAGES>;

// 自动推导生成带前缀的路由对象,类型完全匹配实际值
const ROUTES = getRoutesForPages(PAGES, ROOT);

// 现在Route类型会是 '/admin/p-1' | '/admin/p-2'
export type Route = ReverseMap<typeof ROUTES>;

核心要点

  • PrefixedRoutes映射类型:遍历原对象的每个键,用模板字面量类型把前缀和原路由值拼接成精确的字面量类型,比如/${Root}/${T[K]}会把admin和p-1拼成/admin/p-1。
  • const类型参数Root:让传入的root参数保留字面量类型(比如'admin'而不是宽泛的string),这样模板字面量才能生成精确的路径类型。
  • 不修改原对象:原PAGES是as const断言的只读对象,直接修改会触发运行时错误,创建新对象存储结果更安全可靠。

这样修改后,Route类型就能正确生成带前缀的路径联合类型,同时getRoutesForPages可以复用在其他模块,传入不同的root生成对应前缀的路由。

内容的提问来源于stack exchange,提问作者Ewan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:30:55