如何基于import.meta.glob加载的JSON创建CourseId联合类型?
问题:如何基于动态加载的JSON文件生成对应ID的联合类型?
我通过import.meta.glob加载了一批内部包含id字段的JSON文件,相关代码如下:
export type CourseInfo = { id: string; name: string; fullName: string; sku: string | null; par: string; buyCourseDescription: string | null; price: string; onSaleFrom: string | null; isFirm: boolean; holes: CourseHoleInfo[]; courseImage: string; courseBuyImage: string; courseLogo: string | null; courseLogoHorizontal: string | null; status: CourseAvailability; overrideData: object; }; const courseModules = import.meta.glob('./*.json', { eager: true, }); const COURSES: CourseInfo[] = []; Object.keys(courseModules).forEach(key => { COURSES.push(courseModules[key].default); }); const courseIds = COURSES.map(({id}) => id);
目前courseIds数组的值类似['a', 'b', 'c', ……],我希望创建一个仅允许这些值的联合类型(即type CourseId = 'a' | 'b' | 'c' | ……),请问这是否可行?
解决方案
可行,通过调整类型推断逻辑就能实现,具体步骤如下:
- 移除
COURSES的显式CourseInfo[]类型声明,让TypeScript自动推断其类型,同时用as const断言来保留JSON中id的具体字面量类型,避免被宽泛化为string。 - 利用
typeof操作符从COURSES的类型中提取所有id的联合类型。
修改后的代码如下:
export type CourseInfo = { id: string; name: string; fullName: string; sku: string | null; par: string; buyCourseDescription: string | null; price: string; onSaleFrom: string | null; isFirm: boolean; holes: CourseHoleInfo[]; courseImage: string; courseBuyImage: string; courseLogo: string | null; courseLogoHorizontal: string | null; status: CourseAvailability; overrideData: object; }; const courseModules = import.meta.glob('./*.json', { eager: true, }); // 自动推断类型并冻结字面量 const COURSES = Object.values(courseModules).map(module => module.default) as const; // 提取所有id的联合类型 type CourseId = typeof COURSES[number]['id']; // 创建符合联合类型的id数组 const courseIds = COURSES.map(({id}) => id) as CourseId[];
关键说明
as const会让TypeScript将COURSES中的每个元素视为不可变的常量,从而保留id的具体字符串字面量(比如'a'、'b'),而不是统一识别为string。typeof COURSES[number]['id']会遍历COURSES的所有元素,提取每个元素id字段的类型,自动组合成联合类型。- 后续JSON文件的
id新增或修改时,CourseId类型会自动同步更新,无需手动维护。
内容的提问来源于stack exchange,提问作者reintroducing
相关产品推荐
相关产品推荐

