如何为含特定参数约束的JavaScript函数编写TypeScript声明文件?
TypeScript声明文件实现方案
要实现你需要的类型约束,我们可以利用TypeScript的模板字面量类型和递归条件类型,把字符串中{}的数量和参数param2的长度做关联,同时限制参数类型。
步骤1:定义辅助类型
先写两个辅助类型,用来处理占位符计数和参数类型匹配:
// 计算字符串中{}的出现次数,返回对应长度的元组(确保至少有1个占位符) type CountPlaceholders<S extends string, Acc extends unknown[] = []> = S extends `${string}{}${infer Rest}` ? CountPlaceholders<Rest, [...Acc, unknown]> : Acc['length'] extends 0 ? never // 没有占位符的字符串会被排除 : Acc; // 根据占位符数量,确定param2的合法类型 type Param2Type<N extends unknown[]> = N['length'] extends 1 ? string | number | [string | number] // 1个占位符时,支持单个值或单元素数组 : { [K in keyof N]: string | number }; // 多个占位符时,必须是对应长度的数组
步骤2:编写函数声明
基于辅助类型,写出myFunction的TypeScript声明:
declare function myFunction< S extends string, P extends CountPlaceholders<S> >( param1: S, param2: Param2Type<P> ): string;
验证效果
下面是合法和非法调用的示例:
// ✅ 合法调用 myFunction("The boat is {}", "yellow"); myFunction("The boat is {}", 123); myFunction("The boat is {}", ["yellow"]); myFunction("There are {} out of {} students here", [20, 30]); myFunction("There are {} out of {} students here", ["twenty", "thirty"]); // ❌ 非法调用(TypeScript会报错) myFunction("No placeholders", "test"); // param1没有占位符 myFunction("One {}", ["a", "b"]); // 数组长度和占位符数量不匹配 myFunction("Two {} {}", "single"); // 单个值无法匹配2个占位符
原理说明
CountPlaceholders通过递归遍历字符串,每找到一个{}就往累加元组里添加元素,最终返回的元组长度就是占位符数量;如果没有占位符,返回never来排除这类字符串。Param2Type根据占位符数量动态调整param2的类型:1个占位符时支持单个值或数组,多个占位符时强制要求对应长度的数组,元素只能是字符串或数字。- 泛型关联了
param1的字符串类型和占位符数量,TypeScript会自动推断param2的合法类型,实现严格的类型检查。
内容的提问来源于stack exchange,提问作者Abc
相关产品推荐
相关产品推荐

