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

TypeScript接口中定义兼容所有基类子类数组的正确语法是什么?

TypeScript 基类型子类型数组声明方案

普通混合存储场景直接用 SomeBase[] 即可

TypeScript 采用结构类型系统,所有继承/符合SomeBase结构的子类型实例,都可以直接赋值给SomeBase类型的变量,完全不需要枚举所有子类,后续新增继承SomeBase的接口也无需修改Foo的定义,写法如下:

interface SomeBase {}
interface A extends SomeBase { aProp: string }
interface B extends SomeBase { bProp: number }

interface Foo {
  bar: SomeBase[]
}

// 示例使用:混合放入A、B实例完全合法
const test: Foo = {
  bar: [
    { aProp: 'test' },
    { bProp: 123 }
  ]
}

需要保留子类型完整信息时用泛型约束

如果你需要bar数组只能存某一种特定子类型的实例、且要保留子类型独有的属性类型提示,可以给Foo加带约束的泛型,对应你提到的<? extends SomeBase>的语法等价于TS中的T extends SomeBase:

// 泛型T默认值设为SomeBase,不需要指定类型时可以直接用Foo
interface Foo<T extends SomeBase = SomeBase> {
  bar: T[]
}

// 示例1:指定只能存A类型的数组
const fooA: Foo<A> = {
  bar: [{ aProp: 'a' }]
}
// 此时fooA.bar[0].aProp 会有完整的类型提示,不会丢失属性

// 示例2:默认情况和直接写SomeBase[]效果一致,支持混合存储
const fooMix: Foo = {
  bar: [
    { aProp: 'a' },
    { bProp: 123 }
  ]
}

补充说明

如果需要从SomeBase[]类型的数组中取出元素调用子类型独有的属性/方法,只需要做类型收窄即可,比如使用if('aProp' in item)判断或者自定义类型谓词,即可获得对应子类型的类型提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:27:05