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

TypeScript动态添加对象属性并获取类型提示问题求助

问题排查与修复

你的代码存在两个核心问题:

  1. 函数重载的实现返回类型不匹配:重载定义了数组输入返回数组类型,但实现函数的返回类型标注为T & S,和数组类型冲突,导致TypeScript无法正确推断类型。
  2. Object.assign修改原对象:原代码直接修改传入的data对象,会产生意外副作用(比如原user或users会被强制添加新属性)。

修复后的代码

// 重载定义:明确数组和单个对象的输入输出类型
function addProperties<T extends object, S extends object>(data: T[], properties: S): (T & S)[];
function addProperties<T extends object, S extends object>(data: T, properties: S): T & S;
function addProperties<T extends object, S extends object>(data: T | T[], properties: S) {
    if (Array.isArray(data)) {
        // 返回新数组,每个元素是原对象和属性的合并(不修改原对象)
        return data.map(item => ({ ...item, ...properties })) as (T & S)[];
    }
    // 返回新对象,不修改原对象
    return { ...data, ...properties } as T & S;
}

interface User {
    firstname: string;
    lastname: string;
}

let user: User = {
    firstname: 'John',
    lastname: 'Doe',
};

let users: User[] = [
    {
        firstname: 'John',
        lastname: 'Doe',
    },
    {
        firstname: 'Peter',
        lastname: 'Pan',
    }
];

const newUsers = addProperties(users, {
    foo: 'bar',
    active: true
});

const newUser = addProperties(user, {
    foo: 'bar',
    active: true
});

console.log(newUser.firstname);
console.log(newUser.lastname);
console.log(newUser.foo); // 现在可获得自动补全
console.log(newUser.active); // 现在可获得自动补全

关键修改说明

  • 调整实现函数参数类型:将data的类型改为T | T[],覆盖单个对象和数组两种输入场景。
  • 用对象展开替代Object.assign:{ ...item, ...properties }会创建全新对象,避免修改原数据的副作用,同时类型合并逻辑更清晰。
  • 添加类型断言:通过as (T & S)[]和as T & S告诉TypeScript返回值符合重载定义的类型,解决类型不匹配问题。
  • 保留重载定义:确保TypeScript能根据输入类型自动推断正确的返回类型,提供完整的属性自动补全支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:21:16