You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为包含不同类型对象的数组编写TypeScript类型定义

如何为包含不同对象的数组编写TypeScript类型?

你遇到的问题核心是联合类型的数组写法错误,我来帮你修正并解释清楚:

正确的类型定义写法

首先我们先把两种不同结构的对象分别定义成独立类型,再把它们组成联合类型的数组:

// 定义单选项的对象类型
type SingleAnswer = {
  id: string;
  answer: string | boolean; // 对应你提到的string/boolean类型
};

// 定义多选项的对象类型
type MultiAnswer = {
  id: string;
  answers: { id: string }[];
};

// 数组类型:每个元素可以是SingleAnswer或MultiAnswer
type AnswerList = (SingleAnswer | MultiAnswer)[];

验证示例

用你给出的数组测试,完全符合类型要求:

const testArray: AnswerList = [
  { "id": "test", "answer": "1" },
  { "id": "test_multi", "answers": [ { "id": "skill_1" }, { "id": "skill_2" } ] }
];

为什么你之前的写法不对?

第一种写法的问题

你写的:

prop: { id: string; answer: string | boolean | { id: string; answers: { id: string }[]} }[];

这个类型是把answers结构塞到了answer属性里,意味着每个对象都有answer字段,而answer的取值可以是字符串、布尔值,或者一个带answers的对象——这和你示例里的数组结构完全不符(示例里一个对象是answer,另一个是answers字段,不是嵌套在answer里)。

第二种写法的问题

你写的:

{ id: string; answer: string | boolean; } | { id: string; answers: { id: string }[] }[];

这里的括号位置错了!这个类型的意思是:要么是单个SingleAnswer对象,要么是全MultiAnswer对象的数组,而不是“数组里每个元素可以是两种类型之一”。正确的应该把联合类型整体括起来,再加上数组符号[],也就是(TypeA | TypeB)[]

进阶:更安全的区分联合类型

如果后续需要对数组元素做类型判断,可以给每个类型加一个区分标记(discriminated union),这样TypeScript能更精准地推断类型:

type SingleAnswer = {
  id: string;
  type: 'single'; // 区分标记
  answer: string | boolean;
};

type MultiAnswer = {
  id: string;
  type: 'multi'; // 区分标记
  answers: { id: string }[];
};

type AnswerList = (SingleAnswer | MultiAnswer)[];

// 处理元素时的类型安全判断
function handleAnswer(item: SingleAnswer | MultiAnswer) {
  if (item.type === 'single') {
    // 这里TypeScript明确知道item是SingleAnswer类型,可以安全访问answer
    console.log('单选项答案:', item.answer);
  } else {
    // 这里明确是MultiAnswer类型,可安全访问answers
    console.log('多选项答案:', item.answers);
  }
}

内容的提问来源于stack exchange,提问作者PaulB

火山引擎 最新活动