如何向Typescript中嵌套对象的每个子对象添加属性?

如何向Typescript中嵌套对象的每个子对象添加属性?,typescript,recursion,Typescript,Recursion,我试图键入一个函数addId,该函数输入一个对象并返回同一个对象,但向每个子对象添加一个属性\u id:string 例如,假设输入是由以下类构造的对象 class A { a: number b: { bb: number } c: number[] constructor() { this.a = 1 this.b = { bb: 2 } this.c = [1,2,3] } } const a = new A() 在这种情况下,addId(a

我试图键入一个函数
addId
,该函数输入一个对象并返回同一个对象,但向每个子对象添加一个属性
\u id:string

例如,假设输入是由以下类构造的对象

class A {
  a: number
  b: { bb: number }
  c: number[]

  constructor() {
    this.a = 1
    this.b = { bb: 2 }
    this.c = [1,2,3]
  }
}
const a = new A()
在这种情况下,
addId(a)
将返回

A {
  _id: 'id1'
  a: 1
  b: { bb: 2, _id: 'id2' }
  c: [1,2,3]
}
addId
的参数可以是任何类的对象,而不是类
A
。该参数可以从json、对象和数组递归构建,并且可以具有任意嵌套深度

我不是在寻找
addId
的实现,只是返回类型。我认为解决方案将使用与此处定义的
DeepReadonly
类型类似的技术:

如何:

type Smart<T> =
  T extends Function ? T :
  T extends object ? (
    { [K in keyof T]: Smart<T[K]> } &
    (T extends readonly any[] ? unknown : { _id: string })
  ) : T

你好,jcalz。也许我可以解释一下我的编辑。这里的一般编辑道德与维基百科很相似——鼓励投稿人以技术性的方式简洁地写作。编辑也采取同样的方法——编辑材料是为了提高拼写、语法、简洁性等。编辑经常看到“希望有帮助”和“好运”以及签名和其他签名,通常一看到就删除。这不是针对个人的-我们不会从一个人而不是另一个人身上删除它们。我已恢复了此编辑,但如果在不久的将来收到一系列此类警告,我会很不高兴。如果你必须对我的答案做一些小的修改,请调整你自己的节奏(我在过去与连载编辑有过一些不愉快的经历)。谢谢你的恢复,谢谢。我总体上同情连载编辑的问题——我的理解是,这有点像,但有一些警告(特别是关于编辑率,如你所说)。我会尽量放松的!
declare class A {
  a: number
  b: { bb: number }
  c: number[]
}
type SmartA = Smart<A>;
/*
type SmartA = {
    a: number;
    b: {
        bb: number;
    } & {
        _id: string;
    };
    c: number[];
} & {
    _id: string;
}
*/