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

如何根据数组元素类型重写Array的push方法?

TypeScript中根据数组元素类型处理push的正确方式

你的代码里用instanceof Array<Foo>和instanceof Array<Bar>是无效的——TypeScript的泛型信息在编译为JavaScript后会被完全擦除,运行时根本不存在Array<Foo>或Array<Bar>这类具体类型,所以这两个判断永远不会生效。

下面是几种可行的解决方法:

方法一:自定义类型守卫函数

通过检查数组元素的结构来确定数组类型,同时让TypeScript能正确推断类型:

interface Foo {
    id: number
}
interface Bar {
    name: string
}

// 判断数组是否为Foo[]的类型守卫
function isFooArray(arr: unknown): arr is Foo[] {
    return Array.isArray(arr) && arr.every(item => 
        typeof item === 'object' && item !== null && 
        'id' in item && typeof (item as Foo).id === 'number'
    );
}

// 判断数组是否为Bar[]的类型守卫
function isBarArray(arr: unknown): arr is Bar[] {
    return Array.isArray(arr) && arr.every(item => 
        typeof item === 'object' && item !== null && 
        'name' in item && typeof (item as Bar).name === 'string'
    );
}

function func1(array_var: Foo[] | Bar[]) {
    if (isFooArray(array_var)) {
        array_var.push({ id: 10 });
    } else if (isBarArray(array_var)) {
        array_var.push({ name: "Stack" });
    }
}

方法二:通过数组元素特征快速判断(适合非空数组)

如果能确定数组不为空,可以通过第一个元素的属性来推断类型:

interface Foo {
    id: number
}
interface Bar {
    name: string
}

function func1(array_var: Foo[] | Bar[]) {
    // 处理空数组的业务逻辑,比如默认处理或抛出错误
    if (array_var.length === 0) return;

    const firstItem = array_var[0];
    if ('id' in firstItem && typeof firstItem.id === 'number') {
        (array_var as Foo[]).push({ id: 10 });
    } else if ('name' in firstItem && typeof firstItem.name === 'string') {
        (array_var as Bar[]).push({ name: "Stack" });
    }
}

方法三:扩展Array的push方法(利用类型推断)

如果你的目标是给数组添加一个类型安全的push方法,不需要运行时判断,直接通过TypeScript的类型约束实现:

interface Foo {
    id: number
}
interface Bar {
    name: string
}

declare global {
    interface Array<T> {
        pushTyped(item: T): void;
    }
}

Array.prototype.pushTyped = function<T>(this: T[], item: T) {
    this.push(item);
};

// 使用示例
const fooList: Foo[] = [];
fooList.pushTyped({ id: 10 }); // 类型校验通过

const barList: Bar[] = [];
barList.pushTyped({ name: "Stack" }); // 类型校验通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:50:20