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

TypeScript中能否在tsc编译阶段抛出自定义错误拦截非法传参?

实现方案

可以通过TS原生类型系统实现编译期参数校验,无需依赖第三方工具,核心是通过条件类型将非法参数组合排除在入参允许范围之外,不需要在函数体内部做运行时判断,调用时传非法参数会直接触发TS编译报错。

示例1:字符串字面量参数校验

针对你给出的f函数场景,有两种常用实现方式:

方案1:枚举合法参数组合

适合合法参数组合数量较少的场景,直接把所有合法的参数对定义为入参的联合类型:

// 定义所有允许的参数组合
type ValidInput = 
  | ["A", "C"]
  | ["A", "D"]
  | ["B", "C"]

function f(...args: ValidInput) {
  const [arg1, arg2] = args
  // 执行其他业务逻辑
}

调用校验效果:

f("A", "C"); // 正常编译
f("A", "D"); // 正常编译
f("B", "C"); // 正常编译
f("B", "D"); // 编译报错:类型“"D"”的参数不能赋给类型“"C"”的参数

方案2:泛型条件类型排除非法组合

适合参数可选值多、枚举所有合法组合成本高的场景,通过条件类型直接拦截非法组合:

function f<T extends "A" | "B", U extends "C" | "D">(
  arg1: T,
  // 如果arg1是"B",则arg2不能为"D",否则类型为never
  arg2: T extends "B" ? U extends "D" ? never : U : U
) {
  // 执行其他业务逻辑
}

调用校验效果和方案1完全一致,传f("B", "D")时会因为"D"无法赋值给never类型触发编译报错。

示例2:数值参数校验(旧示例root函数)

针对数值入参的场景,仅对字面量传参有效,如果入参是运行时才能确定值的变量(比如接口返回值、用户输入值),TS编译期无法感知运行时数值,这种场景只能加运行时判断,无法做编译期拦截。
字面量传参的实现如下:

// 辅助类型:判断数值是否为偶数
type IsEven<T extends number> = `${T}` extends `${infer N extends number}` 
  ? N extends 0 ? false : `${N}` extends `${string}${0|2|4|6|8}` ? true : false 
  : false
// 辅助类型:判断数值是否为负数
type IsNegative<T extends number> = `${T}` extends `-${number}` ? true : false

function root<T extends number, U extends number>(
  radical: T,
  // 如果根指数是偶数,则被开方数不能为负数,否则类型为never
  radicand: IsEven<T> extends true ? IsNegative<U> extends true ? never : U : U
) {
  // 执行计算逻辑
  return Math.pow(radicand, 1/radical)
}

调用校验效果:

root(2, 4) // 正常编译
root(2, -4) // 编译报错:类型“-4”的参数不能赋给类型“never”的参数
root(3, -8) // 正常编译

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:12:02