You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript能否从动态未知数组获取精确字面量联合类型?

问题根源

问题出在Object.keys()的内置类型定义上:TypeScript 中Object.keys()的返回值固定为string[]类型,这是TS的有意设计——由于JS对象在运行时可能存在类型定义里没声明的额外属性,TS出于类型安全考虑,不会自动把返回值推导为对象键的字面量联合类型。
你给动态生成的数组加as const时,只能把string[]断言为只读的字符串数组,没法收窄到具体的字符串字面量,所以typeof IconNames[number]最终推导结果就是string。而你手写的IconSizes是直接写死的字符串字面量数组,加as const后TS能直接推导出每个元素的精确字面量类型,所以能正常得到联合类型。

修复方案

直接通过keyof拿到图标模块的导出键类型,手动给生成的数组做类型断言即可:

import * as Icons from "@icons";

// 先获取图标模块所有导出键的联合类型
type IconNameKey = keyof typeof Icons;
// 对Object.keys的返回值做类型断言
const IconNames = Object.keys(Icons) as readonly IconNameKey[];

const IconSizes = ["sm", "md", "lg"] as const;

// 此时icon类型就能正确推导为所有图标名的联合类型
// type IconProp = { icon: typeof IconNames[number]; size: typeof IconSizes[number] }

如果需要完全和IconSizes一致的只读元组效果,在TS5.0+版本可以配合satisfies做额外校验,避免断言写错类型:

const IconNames = [...Object.keys(Icons)] as const satisfies readonly IconNameKey[];

注意:不建议通过修改TS内置Object.keys类型定义的方式强制推导出字面量联合,这种写法会绕过TS的安全检查,如果导入的图标模块被打包工具注入了额外属性(比如模块标识、默认导出别名等),可能会出现类型声明和运行时实际值不匹配的问题。

内容的提问来源于stack exchange,提问作者Paraform Creative

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:21:13