保留Config接口时,如何提取ConfigKey联合类型?
保留Config接口同时提取推断的ConfigKey联合类型
问题场景
你有如下TypeScript代码,希望在保留Config接口的前提下,提取出CONFIG_ARR中所有key值的联合类型ConfigKey:
interface Config { key: string url: string } const CONFIG_ARR: readonly Config[] = [ { key: 'home', url: '/home' }, { key: 'product', url: '/product' } ] as const
直接使用type ConfigKey = typeof CONFIG_ARR[number]['key']会得到string类型,而非期望的'home' | 'product'——因为显式标注readonly Config[]会把key的字面量类型拓宽为string。
解决方案
方法1:使用satisfies关键字(TypeScript 4.9+ 推荐)
satisfies可以验证值是否符合指定类型,但不会覆盖TypeScript对值的字面量类型推断,完美适配你的需求:
interface Config { key: string; url: string; } // 验证CONFIG_ARR符合readonly Config[]类型,同时保留字面量推断 const CONFIG_ARR = [ { key: 'home', url: '/home' }, { key: 'product', url: '/product' } ] as const satisfies readonly Config[]; // 成功推断出联合类型 'home' | 'product' type ConfigKey = typeof CONFIG_ARR[number]['key'];
方法2:TypeScript 4.9以下版本兼容方案
可以通过类型交叉或编译时校验来实现:
方案A:类型交叉标注
interface Config { key: string; url: string; } const CONFIG_ARR: readonly Config[] & typeof CONFIG_ARR = [ { key: 'home', url: '/home' }, { key: 'product', url: '/product' } ] as const; type ConfigKey = typeof CONFIG_ARR[number]['key']; // 'home' | 'product'
方案B:编译时类型校验
先定义常量并保留字面量推断,再通过条件类型验证其是否符合Config接口,确保类型安全:
interface Config { key: string; url: string; } const CONFIG_ARR = [ { key: 'home', url: '/home' }, { key: 'product', url: '/product' } ] as const; // 编译时校验:如果CONFIG_ARR不符合Config数组,这里会返回false并报错 type ValidateConfig = typeof CONFIG_ARR extends readonly Config[] ? true : false; type ConfigKey = typeof CONFIG_ARR[number]['key']; // 'home' | 'product'
总结
优先使用satisfies方案,语法简洁且类型安全,既能保证CONFIG_ARR符合Config接口定义,又能让TypeScript准确推断出key的字面量联合类型。
内容的提问来源于stack exchange,提问作者Ric Donati
相关产品推荐
相关产品推荐

