如何用TypeScript定义嵌套对象的BraSize联合类型?
问题与解决方案
问题背景
已有如下常量对象:
const braSizeObj = { IT: { '0': ['AA', 'A', 'B'], '1': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'], '2': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'], '5': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], }, US: { '2': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'], '3': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'], '4': ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], }, } as const;
需要完成两个目标:
- 从
braSizeObj中定义BraSize类型,使其为所有地区下的尺寸键联合类型:"0" | "1" | "2" | "5" | "3" | "4" - 解决类型错误:当使用类型为
"IT"|"US"的braLocale索引braSizeObj后,再访问"0"键时TS会报错——因为只有IT地区包含该键,两者共有的键仅为"2"。
解决方案
1. 定义BraSize联合类型
利用TypeScript的索引类型和keyof操作符,遍历所有地区的子对象键,即可快速生成目标联合类型:
type BraSize = keyof (typeof braSizeObj)[keyof typeof braSizeObj];
这里(typeof braSizeObj)[keyof typeof braSizeObj]会得到IT和US子对象的联合类型,再通过keyof提取所有子对象的键,最终得到所有尺寸键的联合类型。
2. 解决索引时的类型错误
直接用braLocale索引后访问非共有键会触发报错,因为TS无法确定当前地区是否包含该键。以下两种方式可解决问题:
方式一:类型守卫缩小范围
先通过判断确定当前地区,再访问对应键:
type BraLocale = keyof typeof braSizeObj; const braLocale: BraLocale = 'IT'; let braSize; if (braLocale === 'IT') { braSize = braSizeObj[braLocale]['0']; // 无错误,已确定为IT地区 } else { // 处理US地区的逻辑 }
方式二:定义地区关联的尺寸类型
通过泛型定义一个与地区绑定的尺寸类型,让TS自动校验传入的尺寸是否符合当前地区:
type BraLocale = keyof typeof braSizeObj; type BraSizeByLocale<L extends BraLocale> = keyof typeof braSizeObj[L]; function getBraSize<L extends BraLocale>(locale: L, size: BraSizeByLocale<L>) { return braSizeObj[locale][size]; } // 合法调用:IT地区支持"0"键 getBraSize('IT', '0'); // 触发报错:US地区不支持"0"键,符合预期 getBraSize('US', '0');
内容的提问来源于stack exchange,提问作者Dmytro
相关产品推荐
相关产品推荐

