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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:40:39