TypeScript如何根据前一个参数值实现条件类型校验
实现方案
这个需求完全可以通过泛型实现,核心思路是通过泛型约束捕获第一个参数的字面量类型,再通过类型映射表关联两个参数的类型对应关系,就能做到第二个参数的类型随第一个参数的取值动态适配。
具体实现代码
首先定义两个参数的类型映射关系,把第一个参数的每个可能取值,和其对应的第二个参数类型做绑定:
type Param1Type = "Morning" | "Afternoon" | "Evening"; type MorningType = "test1" | "test2" | "test3"; type AfternoonType = "example1" | "example2" | "example3"; type EveningType = "value1" | "value2" | "value3"; // 参数1到参数2的类型映射表 type Param2TypeMap = { Morning: MorningType; Afternoon: AfternoonType; Evening: EveningType; };
之后给函数添加泛型约束,限定泛型为第一个参数的字面量子类型,第二个参数的类型直接从映射表中取对应泛型的类型即可:
export const TEST = <T extends Param1Type>(param1: T, param2: Param2TypeMap[T]) => { // 函数内部逻辑 // 内部判断param1取值时,TS会自动收窄param2的类型,不需要额外做类型断言 switch(param1) { case "Morning": // 此处param2自动推导为MorningType break; case "Afternoon": // 此处param2自动推导为AfternoonType break; case "Evening": // 此处param2自动推导为EveningType break; } };
校验效果
实现完成后,TS会自动对入参做动态校验:
- 合法调用不会报类型错误:
TEST("Morning", "test2")TEST("Afternoon", "example3")TEST("Evening", "value1")
- 非法传参会直接抛出类型错误,阻止不符合规则的值传入:
TEST("Morning", "example1")报错,Morning对应的合法param2取值为test1/test2/test3TEST("Evening", "test3")报错,Evening对应的合法param2取值为value1/value2/value3
除了泛型实现外,也可以通过TS函数重载实现同样的效果,但泛型写法代码更简洁,后续扩展时只需要在
Param2TypeMap中补充对应映射关系即可,维护成本更低。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

