TypeScript如何简洁编写值类型随两种mode切换的联合类型?
TypeScript 基于mode属性匹配value类型的简洁实现方案
你原有实现存在两个可优化点:额外定义了冗余的Mode类型,条件类型判断的写法扩展性较差,另外示例中存在笔误:定义的泛型名为ObjectDependsOnMode,实际使用时写为ExtendedObjectDependsOnMode。
以下是三种不同场景下的简洁实现方案:
方案1:联合类型实现(最简洁,无需泛型)
如果mode类型固定只有number/string两种,直接写联合类型最直观,不需要复杂的泛型和条件判断:
// 类型定义 type NumberModeObject = { mode: 'number' value: number [key: string]: any // 支持任意其他自定义属性 } type StringModeObject = { mode: 'string' value: string [key: string]: any } type ModeDependentObject = NumberModeObject | StringModeObject // 示例使用 const testObject: ModeDependentObject = { mode: 'number', pokemon: 'pikachu', value: 25 // TS自动校验为number类型,填字符串会直接报错 }
该方案代码量最少,TS可以自动根据你填写的mode字段校验value类型,不需要额外传入泛型参数。
方案2:简化泛型实现(保留自定义类型传入能力)
如果你需要保留泛型,支持传入特定的结构类型做约束,可以简化掉单独的Mode类型定义:
// 类型定义 type ObjectDependsOnMode<T extends { mode: 'number' | 'string' }> = T & { value: T['mode'] extends 'number' ? number : string } // 示例使用 type TestMode = { mode: 'number', pokemon: 'pikachu', } const testObject: ObjectDependsOnMode<TestMode> = { mode: 'number', pokemon: 'pikachu', value: 25 }
方案3:映射表实现(扩展性最优)
如果后续可能新增更多mode类型(比如boolean/array等),用映射表的方式可读性和可维护性最高,新增类型只需要修改映射表即可:
// 类型定义:mode和value类型的映射关系,新增类型只需要调整这部分 type ModeValueMap = { number: number string: string // 后续可新增比如 boolean: boolean, array: any[] 等规则 } type ObjectDependsOnMode<T extends { mode: keyof ModeValueMap }> = T & { value: ModeValueMap[T['mode']] } // 示例使用 const testObject: ObjectDependsOnMode<{mode: 'string', pokemon: 'pikachu'}> = { mode: 'string', pokemon: 'pikachu', value: '25' // 自动校验为string类型 }
内容的提问来源于stack exchange,提问作者mymactive
相关产品推荐
相关产品推荐

