typescript - 如何为 Typescript 中嵌套对象的每个子对象添加属性?
问题描述
我正在尝试键入一个函数,该函数addId
输入一个对象并返回相同的对象,但_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]
}
参数 toaddId
可以是任何类的对象,而不是具体的 class A
。该参数可以从 json、对象和数组递归构建,并且可以具有任意嵌套深度。
我不是在寻找 的实现addId
,只是在寻找返回类型。DeepReadonly<T>
我认为解决方案将使用与此处定义的类型类似的技术: https ://github.com/piotrwitek/utility-types/blob/master/src/mapped-types.ts
解决方案
怎么样:
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
如果T
是一个非函数对象,那么你肯定想递归到它并Smart<T>
为每个属性做。这适用于数组和常规对象。但是您只想将该_id
属性添加到非数组对象,这就是我进行该T extends readonly any[]
检查的原因。您可以确认它提供了您期望的输出:
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;
}
*/
推荐阅读
- python - 使用 Python 在一台设备中模拟多网络环境
- c - 字符串的内存分配
- python - 多级属性?
- python - 操作数应该只包含一列错误 - to_sql() python mysql
- python - 如何在 python aws lambda 多处理中传递大量内存
- amp-html - AMP 页面不支持我的页面中的 line-clamp 属性。请建议
- python - 通过网状在R中安装Python模块时出错
- javascript - 在 JavaScript 中,如何创建一个接受两个数字和一个数学运算符 + - / * 使用给定数字执行计算的函数
- r - Geom_Text removes geom_bar in ggplot2 R
- node.js - Performance between local database and cloud database