如何为联合类型成员属性匹配的函数设置正确泛型?
修正TypeScript test函数的泛型定义以实现正确类型约束
问题背景
现有如下TypeScript类型与函数定义:
interface A { type: 'a'; state: number; } interface B { type: 'b'; state: string; } type OneOfThem = A | B; function test<T extends OneOfThem>(type: T['type'], state: T["state"]): T { return {type, state} as T; }
预期调用行为:
test('a', 3)类型合法,不应报错test('a', "asd")类型不匹配,应当报错
但当前函数的类型被推断为:
function test<OneOfThem>(type: "a" | "b", state: string | number): OneOfThem
泛型被解析为联合类型,导致state的约束变成string | number,不符合预期的类型校验逻辑。
解决方案
方案1:通过Extract条件类型关联类型
将泛型约束为OneOfThem的type字段取值,利用Extract从联合类型中筛选出对应type的成员,以此精准约束state和返回值的类型:
function test<T extends OneOfThem['type']>( type: T, state: Extract<OneOfThem, { type: T }>['state'] ): Extract<OneOfThem, { type: T }> { return { type, state } as Extract<OneOfThem, { type: T }>; }
方案2:使用映射类型建立类型映射表
提前定义一个映射类型,直接关联type值与对应的接口类型,让泛型基于映射表的键进行约束,逻辑更直观:
type TypeMap = { a: A; b: B; }; function test<T extends keyof TypeMap>( type: T, state: TypeMap[T]['state'] ): TypeMap[T] { return { type, state } as TypeMap[T]; }
效果验证
修改后:
test('a', 3)能正常通过类型检查test('a', "asd")会触发类型错误,提示state应为number类型,符合预期的约束逻辑
内容的提问来源于stack exchange,提问作者FourwingsY
相关产品推荐
相关产品推荐

