如何在TypeScript中使用联合类型搭配对象动态键值?
解决TypeScript联合类型动态属性键的类型报错问题
你遇到的核心问题是:当使用动态属性键[type]时,TypeScript无法自动推断出这个动态生成的对象符合TimetabledClass联合类型的任一成员,会把属性键宽泛地识别为string类型,导致类型不匹配报错。
另外先纠正一个小问题:你代码里的classCode: "string"是字符串字面量类型(只能取"string"这个固定值),应该改成classCode: string(任意字符串类型),否则函数的classCode参数只能传"string",不符合实际使用场景。
下面给出三种可行的解决方案:
方案1:用泛型关联参数与对象类型
通过泛型约束type参数,让TypeScript明确知道传入的type对应的是联合类型中的哪个属性,从而精准推断对象结构:
type TimetabledClass = { classCode: string; students: string[]; } | { classCode: string; teachers: string[]; }; function getTimetabledClassEnrolments<T extends 'students' | 'teachers'>( type: T, classCode: string ) { const timetabledClasses: TimetabledClass[] = []; const enrolments = ['person1', 'person2']; // 利用泛型分支推断对应类型 const newClass = { classCode, [type]: enrolments } as T extends 'students' ? { classCode: string; students: string[] } : { classCode: string; teachers: string[] }; timetabledClasses.push(newClass); return timetabledClasses; }
方案2:直接类型断言(简单但需确保安全)
如果能保证传入的type和enrolments的类型完全匹配,可以直接把对象断言为TimetabledClass:
type TimetabledClass = { classCode: string; students: string[]; } | { classCode: string; teachers: string[]; }; function getTimetabledClassEnrolments( type: 'students' | 'teachers', classCode: string ) { const timetabledClasses: TimetabledClass[] = []; const enrolments = ['person1', 'person2']; timetabledClasses.push({ classCode, [type]: enrolments } as TimetabledClass); // 直接断言为目标联合类型 return timetabledClasses; }
方案3:重构为映射类型(扩展性更强)
如果后续可能新增更多类似属性(比如staff),用映射类型可以避免重复定义联合类型:
// 定义所有可能的 enrolment 类型 type EnrolmentType = 'students' | 'teachers'; // 用映射类型生成目标类型 type TimetabledClass<T extends EnrolmentType = EnrolmentType> = { classCode: string; } & { [K in T]: string[] }; function getTimetabledClassEnrolments<T extends EnrolmentType>( type: T, classCode: string ) { const timetabledClasses: TimetabledClass[] = []; const enrolments = ['person1', 'person2']; const newClass: TimetabledClass<T> = { classCode, [type]: enrolments }; timetabledClasses.push(newClass); return timetabledClasses; }
内容的提问来源于stack exchange,提问作者badsector
相关产品推荐
相关产品推荐

