如何用TypeScript提取嵌套对象中shoeSizeLocale的联合类型
从对象中提取特定属性的字符串联合类型
问题场景
现有如下TypeScript对象:
const countrySize = { "af":{ "name":"Afghanistan", "shoeSizeLocale":"EU/IT" }, "al":{ "name":"Albania", "shoeSizeLocale":"AU" }, "dz":{ "name":"Algeria", "shoeSizeLocale":"EU/IT" }, "ar":{ "name":"Argentina", "shoeSizeLocale":"US/CA" }, // ... 其他国家数据 }
需要提取shoeSizeLocale的所有取值,生成联合类型:
type ShoeLocale = "EU/IT" | "US/CA" | "AU"
尝试了以下代码,但得到的类型是string,无法达到预期:
type CountryCodes = typeof countrySize; type CountryCodesKeys = keyof CountryCodes; type ShoeLocale = CountryCodes[CountryCodesKeys]["name"];
解决方案
问题的核心是TypeScript默认会将对象字面量的属性值推断为宽泛的string类型,而非具体的字符串字面量。要保留字面量类型,可通过以下两种方法解决:
方法一:使用as const断言
修改对象定义,添加as const强制TypeScript将所有属性值推断为字面量类型:
const countrySize = { "af":{ "name":"Afghanistan", "shoeSizeLocale":"EU/IT" }, "al":{ "name":"Albania", "shoeSizeLocale":"AU" }, "dz":{ "name":"Algeria", "shoeSizeLocale":"EU/IT" }, "ar":{ "name":"Argentina", "shoeSizeLocale":"US/CA" }, // ... 其他国家数据 } as const;
同时修正类型提取代码(原代码误取了name属性,应改为shoeSizeLocale):
type CountryCodes = typeof countrySize; type CountryCodesKeys = keyof CountryCodes; type ShoeLocale = CountryCodes[CountryCodesKeys]["shoeSizeLocale"];
此时ShoeLocale会被正确推断为"EU/IT" | "AU" | "US/CA"。
方法二:通过泛型函数推导
如果不想修改原对象的断言方式,可借助泛型函数来推导字面量类型:
function createCountrySize<T extends Record<string, { name: string; shoeSizeLocale: string }>>(obj: T) { return obj; } const countrySize = createCountrySize({ "af":{ "name":"Afghanistan", "shoeSizeLocale":"EU/IT" }, "al":{ "name":"Albania", "shoeSizeLocale":"AU" }, "dz":{ "name":"Algeria", "shoeSizeLocale":"EU/IT" }, "ar":{ "name":"Argentina", "shoeSizeLocale":"US/CA" }, // ... 其他国家数据 }); type CountryCodes = typeof countrySize; type CountryCodesKeys = keyof CountryCodes; type ShoeLocale = CountryCodes[CountryCodesKeys]["shoeSizeLocale"];
这种方式同样能让TypeScript保留shoeSizeLocale的具体字面量类型,生成期望的联合类型。
内容的提问来源于stack exchange,提问作者Dmytro
相关产品推荐
相关产品推荐

