如何从require引入的JSON包数组定义字符串字面量联合类型
解决从JSON包生成字符串字面量联合类型的问题
问题根源
用require引入JSON包的数组时,TypeScript默认将数组元素类型推断为string,而非具体的字符串字面量,导致typeof namesArr[number]得到的是any或string,无法生成期望的联合类型。
解决办法
办法1:使用as const断言锁定字面量类型
直接对导入的数组使用const断言,强制TypeScript将其解析为只读的字面量数组:
// require方式 const namesArr = require('names-package') as const; type Names = typeof namesArr[number]; // 类型为 "John" | "Lily" | "Roy" // import方式(需开启tsconfig的resolveJsonModule) import namesArr from 'names-package'; const fixedNames = namesArr as const; type Names = typeof fixedNames[number];
办法2:为第三方包编写类型声明
如果需要长期使用该包,建议在项目中添加自定义类型声明:
- 在项目根目录创建
@types/names-package/index.d.ts文件 - 写入以下内容:
declare module 'names-package' { export type NamesUnion = "John" | "Lily" | "Roy"; const namesArray: readonly NamesUnion[]; export default namesArray; }
- 后续导入时,TypeScript会自动识别类型:
import namesArr from 'names-package'; type Names = typeof namesArr[number]; // 直接得到联合类型
办法3:工具类型结合动态断言(灵活场景)
若不想手动枚举字面量,可通过工具类型提取:
type StringLiteralUnion<T extends readonly string[]> = T[number]; // 断言导入的数组为只读字面量数组 const namesArr = require('names-package') as readonly ["John", "Lily", "Roy"]; type Names = StringLiteralUnion<typeof namesArr>;
内容的提问来源于stack exchange,提问作者jeancallisti
相关产品推荐
相关产品推荐

