如何声明仅含字符串或仅含对象的TypeScript数组
问题分析与解决方案
为什么会出现这个错误?
你声明的displayValues: string[] | {displayName: string}[]是两种数组类型的联合,但TypeScript在处理联合类型数组的push操作时,会要求传入的元素必须同时兼容两种数组的元素类型——也就是取string和{displayName: string}的交集(string & {displayName: string})。显然这两种类型没有交集,所以会抛出类型不匹配的错误。
另外,初始值是空数组[],TypeScript无法推断它属于哪种数组类型,即使加类型守卫,因为空数组没有元素可供判断,也无法缩小联合类型的范围,所以错误依然存在。
实现“数组仅含单一类型”的可行方案
方案1:使用泛型固定实例类型(推荐)
通过泛型让每个类实例只能对应一种数组类型,从根源上避免混合类型的问题:
class DataHolder<T extends string | { displayName: string }> { displayValues: T[] = []; addValue(value: T) { this.displayValues.push(value); } } // 创建仅存字符串的实例 const stringHolder = new DataHolder<string>(); stringHolder.addValue('some string'); // 正常执行 // 创建仅存对象的实例 const objectHolder = new DataHolder<{ displayName: string }>(); objectHolder.addValue({ displayName: 'test' }); // 正常执行
方案2:用区分联合类型包裹数组
给数组添加一个类型标记,通过类型守卫明确当前数组的类型,确保操作的安全性:
// 定义带类型标记的联合类型 type StringArrayWrapper = { type: 'string'; values: string[] }; type ObjectArrayWrapper = { type: 'object'; values: { displayName: string }[] }; class DataManager { private displayValues: StringArrayWrapper | ObjectArrayWrapper = { type: 'string', values: [] }; addString(value: string) { if (this.displayValues.type === 'string') { this.displayValues.values.push(value); } else { throw new Error('当前数组为对象类型,无法添加字符串'); } } addObject(value: { displayName: string }) { if (this.displayValues.type === 'object') { this.displayValues.values.push(value); } else { throw new Error('当前数组为字符串类型,无法添加对象'); } } }
方案3:类型断言(不推荐,需谨慎使用)
如果能确保当前displayValues确实是字符串数组,可以用类型断言跳过检查,但这种方式不安全,可能导致类型不一致:
const value = 'some string'; (this.displayValues as string[]).push(value);
内容的提问来源于stack exchange,提问作者user1902183
相关产品推荐
相关产品推荐

