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

TypeScript中如何限定函数仅接收接口定义的属性值作为参数

实现方案

问题根源是你给APIs显式标注APIRoutes类型时,TS会自动把属性值类型拓宽为普通string,丢失了具体的字面量信息,自然没法做值的合法性校验。按下面的方式改即可:

第一步:修正APIs常量的类型定义

去掉显式的APIRoutes类型注解,用as const把整个对象收窄为只读字面量类型,让TS能精确推断每个属性的具体值:

const APIs = {
  SIGNUP: Config.baseURL + "/signup",
  LOGIN: Config.baseURL + "/login",
} as const;

如果需要保留原来的APIRoutes接口做结构约束,推荐用TS 4.9+支持的satisfies关键字做校验,不会丢失字面量类型推断:

interface APIRoutes {
  SIGNUP: string,
  LOGIN: string
}
const APIs = {
  SIGNUP: Config.baseURL + "/signup",
  LOGIN: Config.baseURL + "/login",
} as const satisfies APIRoutes;

第二步:提取合法路由值的联合类型

直接从APIs的类型里提取所有属性值的联合,作为函数参数的合法类型:

type ValidAPIRoute = typeof APIs[keyof typeof APIs];

第三步:修改函数的参数类型

把第一个参数的类型从string换成上面定义的ValidAPIRoute即可:

const callAPI = async (APIRoute: ValidAPIRoute, body: any, headers: any) => {
  // 你的业务逻辑
}

校验效果

  • callAPI(APIs.SIGNUP, {}, {}):类型校验通过
  • callAPI(APIs.STACKOVERFLOWISAWESOME, {}, {}):直接报类型错误,因为APIs本身不存在这个属性
  • callAPI("/random/route", {}, {}):报类型错误,传入的字符串不在合法路由值范围内

特殊场景处理

如果你的Config.baseURL是动态读取的(比如从环境变量获取,类型本身就是宽泛的string),拼接后的路由值在类型层面也会是普通string,没法直接通过字面量区分,这时候可以用**烙印类型(Branded Type)**给合法路由打标记:

type ValidAPIRoute = string & { __brand: "APIRoute" };

const APIs = {
  SIGNUP: (Config.baseURL + "/signup") as ValidAPIRoute,
  LOGIN: (Config.baseURL + "/login") as ValidAPIRoute,
};

const callAPI = async (APIRoute: ValidAPIRoute, body: any, headers: any) => {
  // 业务逻辑
}

这种方案同样能拦住非法字符串传入,只有你显式标记为ValidAPIRoute的路由值才能正常传参。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:06:47