寻找一种实用的方法来设置或分配对象成员给其他对象,避免使用非空Assert操作符“!“。下面的例子假设formData
可以是任意的JS对象。
some.component.ts
export class SomeComponent {
someModel: SomeModel;
constructor( ) {
this.someModel.set(formData);
}
}
字符串
some-model.model.ts
export class SomeModel {
field1: string;
field2: string;
constructor({ field1 = "", field2 = "" } = {}) {
this.field1 = field1;
this.field2 = field2;
}
setMembers({field1, field2}: {field1?: string | null, field2: string | null} = {}){
this.field1 = field1 !== null && field1 !== undefined ? field1 : this.field1;
this.field2 = field2 !== null && field2 !== undefined ? field2 : this.field2;
}
}
型
有没有更短的方法来定义setMembers
,使setMembers
只分配不为null且未定义的参数?我想要类似下面的通用方法,其中setMembers可重用于其他模型,并且与参数的数量无关:
setMembers(data: Partial<Model>): void {
ModelHelper.set(this, data);
}
型
model/model-helper.ts
export class ModelHelper {
static set<T>(model: T, data: Partial<T>): void {
for (const key of Object.keys(data) as Array<keyof T>) {
if (data[key] !== null && data[key] !== undefined) {
model[key] = data[key] as T[keyof T];
}
}
}
}
型
但我遇到了“类型”字符串|零|undefined'不能赋值给类型'string|“不确定”的问题再次出现。
所以我必须重新定义签名为:
interface IModel {
[key: string]: any;
}
setMembers(data: Partial<IModel>): void {
ModelHelper.set(this, data);
}
型
1条答案
按热度按时间42fyovps1#
您可以编写一个工厂函数,它接受一组键名,并生成一个适当的
setMembers()
方法,该方法的行为符合您的要求。它可以看起来像这样:字符串
返回的方法使用
this
参数,只允许在属性与keys
中的键匹配的对象上调用它。它接受一个可选的data
参数。data
参数的属性也是可选的,它们的类型应该与调用该方法的对象上的相应属性的类型相同,除了它们也可以是null
或undefined
。该实现使用the nullish coalescing operator (
??
),以便复制data
参数的属性,除非它是null
或undefined
。使用
makeSetter()
的最简单方法如下所示:型
因此,当构建
SomeModel
示例时,setMembers
属性将使用makeSetter("field1", "field2")
的结果进行初始化,这是SomeModel
所需的setter方法。当然,这最终导致对每个
SomeModel
示例都不必要地运行makeSetter
。你可以只做其中一个:型
即使这样,也不必要地为
SomeModel
的每个示例创建setMembers
示例属性,而理想情况下它应该是原型上的一个方法。这是可能的,但你需要告诉TypeScript期望这样的事情:型
现在你希望有一些东西可以用于不同的类:
型
Playground链接到代码