如何在TypeScript中根据参数值为另一个参数指定对应Interface
TypeScript 参数关联约束实现方案
问题背景
现有一段TypeScript代码,需要实现函数参数的关联约束:当第一个参数type取值为'group'时,第二个参数entity必须符合Group接口;当type取值为'user'时,entity必须符合User接口。当前代码中TS无法正确推断分支内entity的类型,导致报错。
当前代码示例:
interface Group { name: string isPublic: boolean } interface User { id: string age: number } type EntityType = 'group' | 'user' function doStuff(type: EntityType, entity: Group | User): boolean { if (type === 'group') { return entity.isPublic // TS报错:'isPublic' 属性不存在于 'Group | User' 类型 } if (type === 'user') { return entity.age > 18 // TS报错:'age' 属性不存在于 'Group | User' 类型 } }
解决方案
方法1:函数重载
直接通过函数重载定义不同参数组合的类型规则,外部调用时TS会严格校验参数匹配:
interface Group { name: string isPublic: boolean } interface User { id: string age: number } // 定义两个重载签名,明确参数组合的类型约束 function doStuff(type: 'group', entity: Group): boolean; function doStuff(type: 'user', entity: User): boolean; // 函数实现逻辑,内部可通过类型断言或类型守卫处理联合类型 function doStuff(type: 'group' | 'user', entity: Group | User): boolean { if (type === 'group') { return (entity as Group).isPublic } else { return (entity as User).age > 18 } } // 调用校验示例 doStuff('group', { name: '技术小组', isPublic: true }) // 合法 doStuff('user', { id: 'u1001', age: 22 }) // 合法 doStuff('group', { id: 'u1002', age: 19 }) // TS报错,不符合Group接口
这种方式直观易懂,适合参数组合较少的场景。
方法2:泛型+映射类型
通过映射类型建立type取值与对应接口的关联,用泛型约束参数间的依赖关系,扩展性更强:
interface Group { name: string isPublic: boolean } interface User { id: string age: number } // 定义类型映射表,将EntityType与对应接口绑定 type EntityMap = { group: Group user: User } // 泛型T限定为EntityMap的键,entity自动匹配对应类型 function doStuff<T extends keyof EntityMap>(type: T, entity: EntityMap[T]): boolean { if (type === 'group') { return entity.isPublic // TS自动推断entity为Group类型 } else { return entity.age > 18 // TS自动推断entity为User类型 } } // 调用校验示例 doStuff('group', { name: '开源社区', isPublic: false }) // 合法 doStuff('user', { id: 'u1003', age: 17 }) // 返回false,参数合法 doStuff('user', { name: '测试组', isPublic: true }) // TS报错,不符合User接口
后续如果新增其他实体类型,只需扩展EntityMap即可,无需修改函数定义,适合复杂场景。
内容的提问来源于stack exchange,提问作者Ben Walters
相关产品推荐
相关产品推荐

