如何在多接口场景下为TypeScript工厂模式设置类型
TypeScript工厂函数的类型匹配解决方案
核心问题分析
你遇到的问题本质是无法建立type参数与data类型的强关联——直接用A | B | C会导致TypeScript无法在switch分支中确定data的具体类型,从而抛出类型不匹配的错误。
解决方案:建立类型映射+泛型/函数重载
方案1:类型映射+泛型函数
这种方式通过定义类型映射表,将type字符串与对应接口绑定,再用泛型约束参数的对应关系,从源头确保输入合法性。
步骤1:定义类型映射
先建立type值到对应接口的映射关系:
// 补全pattern类型定义(假设你已有这些类型) interface patternA { /* ... */ } interface patternB { /* ... */ } interface patternC { /* ... */ } interface A { id: number name: string patternA: patternA[] } interface B { id: number name: string patternB: patternB[] } interface C { id: number name: string patternC: patternC[] city: string } // 核心:建立type字符串与接口的映射 type HogeTypeMap = { first: A; second: B; third: C; }; type HogeType = keyof HogeTypeMap; // 自动推导合法type值:'first' | 'second' | 'third'
步骤2:实现泛型工厂函数
通过泛型T约束type和data的对应关系,调用时TypeScript会自动校验输入:
const factory = <T extends HogeType>(type: T, data: HogeTypeMap[T]) => { switch (type) { case 'first': return createHogeA(data as A); case 'second': return createHogeB(data as B); case 'third': return createHogeC(data as C); default: throw new Error(`不支持的类型:${type}`); } }; // 对应的创建函数 const createHogeA = (data: A) => { /* 你的业务逻辑 */ }; const createHogeB = (data: B) => { /* 你的业务逻辑 */ }; const createHogeC = (data: C) => { /* 你的业务逻辑 */ };
方案2:函数重载
如果类型数量不多,函数重载会更直观,每个重载明确对应一种type和data的组合,内部无需类型断言:
// 先定义所有接口和创建函数(同方案1) // 函数重载:每个重载对应一组合法的参数组合 function factory(type: 'first', data: A): ReturnType<typeof createHogeA>; function factory(type: 'second', data: B): ReturnType<typeof createHogeB>; function factory(type: 'third', data: C): ReturnType<typeof createHogeC>; // 实现函数(内部TypeScript能自动识别分支中的data类型) function factory(type: HogeType, data: A | B | C) { switch (type) { case 'first': return createHogeA(data); case 'second': return createHogeB(data); case 'third': return createHogeC(data); default: throw new Error(`不支持的类型:${type}`); } }
效果验证
两种方案都能实现:
- 调用工厂函数时,如果
type和data类型不匹配,TypeScript会直接抛出编译错误 - 分支内部能正确识别
data的具体类型,避免类型错误
内容的提问来源于stack exchange,提问作者kazon
相关产品推荐
相关产品推荐

