如何确保带索引签名的Students对象中所有考试字段都已定义?
问题背景
以下是定义的TypeScript类型及示例对象:
export interface Students { [studentName: string]: Exam[]; } interface Exam { testName: string; testScore: number; } const studentsExample: Students = { john: [ { testName: "Biology", testScore: 92 }, { testName: "Math", testScore: 76 }, ], sarah: [ { testName: "English", testScore: 87 }, { testName: "Economics", testScore: 95 } ] }; const studentsExample2: Students = { john: [ { testName: "Biology", testScore: 92 }, { testName: "Math", testScore: 76 }, ], sarah: [ { testName: "English", testScore: 87 }, { testName: "Economics"} ], };
需要确保Students类型的对象中,每个学生的每门考试都同时定义了testName和testScore字段(即符合studentsExample的格式,而非studentsExample2)。
如果是常规字段的接口,可以通过指定学生名称遍历考试列表校验,但由于Students使用了索引签名,无法预先知晓所有学生名称,请问该如何实现上述校验?
解决方案
可以通过遍历所有学生的考试列表来完成校验,利用Object.values()获取索引签名对象的所有值(即每个学生的Exam[]数组),再逐层检查每个考试对象的必填字段:
function validateStudents(students: Students): boolean { // 遍历所有学生的考试数组集合 for (const exams of Object.values(students)) { // 遍历当前学生的每一门考试 for (const exam of exams) { // 严格检查字段是否存在且类型匹配 if (typeof exam.testName !== 'string' || typeof exam.testScore !== 'number') { return false; } } } return true; } // 测试验证 console.log(validateStudents(studentsExample)); // 输出 true console.log(validateStudents(studentsExample2)); // 输出 false
补充说明
- TypeScript的接口约束仅在编译阶段生效,如果对象是从外部非TS代码传入,仍需要运行时校验来确保数据完整性。
- 上述校验不仅检查字段是否存在,还验证了字段的类型是否符合
Exam接口的定义,避免出现类型不匹配的情况。
内容的提问来源于stack exchange,提问作者random55645
相关产品推荐
相关产品推荐

