如何为包含不同类型对象的数组编写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




