如何创建基于%字符存在性的TypeScript代码检查规则?
能否用TypeScript规则检测函数调用的字符串字面量是否包含%字符?
Roarr logger的某次变更做出了如下规定:当函数第一个参数为字符串类型且调用时传入了多个参数时,第一个字符串必须包含%字符,否则属于不当调用。示例如下:
const log = <T extends string>(message: T, ...args: number[]) => {}; // 合法调用 log('foo'); log('foo %d', 1); // 非法调用 log('foo', 1);
当然可以实现这类检测,甚至能在编译或代码检查阶段就拦截不当调用,具体有两种可行思路:
1. 利用TypeScript类型系统直接约束函数签名
通过模板字面量类型和条件类型,能精准限制函数的参数组合:
// 定义类型判断字符串是否包含% type HasPercent<T extends string> = T extends `${string}%${string}` ? true : false; // 重新约束log函数的参数 const log = <T extends string>( message: T, // 如果字符串包含%,允许传入number类型的可变参数;否则不允许传额外参数 ...args: HasPercent<T> extends true ? number[] : [] ) => {}; // 合法调用,无类型报错 log('foo'); log('foo %d', 1); // 非法调用,TypeScript会直接抛出类型错误 log('foo', 1); // 类型“[string, number]”的参数不能赋给类型“[string]”的参数。
这个实现的核心是HasPercent类型,它通过模板字面量匹配逻辑判断传入的字符串字面量是否包含%字符,再通过条件类型动态决定可变参数的允许范围,从类型层面直接杜绝不符合规则的调用。
2. 编写ESLint规则做代码检查
如果需要在编码过程中实时给出提示,可以基于@typescript-eslint编写自定义规则,核心逻辑如下:
- 识别代码中
log函数的调用节点 - 检查第一个参数是否为字符串字面量
- 当调用存在第二个及以上参数时,判断该字符串字面量是否包含%字符,不包含则抛出lint错误
这种方式适合团队代码规范的落地,能在lint阶段就发现问题。
内容的提问来源于stack exchange,提问作者Gajus
相关产品推荐
相关产品推荐

