如何让TypeScript泛型Angular表单的可选属性在FormBuilder中可选?
如何让模型中的可选属性在Angular FormBuilder中保持可选性?
当前你的TypedFormControls类型使用了-?修饰符,会强制将所有属性转为必填,导致模型里的可选属性在表单构建时也必须定义对应的控件,否则TypeScript会报错。要解决这个问题,需要修改泛型类型的映射逻辑,保留原模型属性的可选性。
解决方案:修改TypedFormControls泛型类型
移除-?修饰符以保留原属性的可选性,同时为表单控件添加null类型支持(符合Angular表单控件值可空的特性):
export type TypedFormControls<T extends Record<any, any>> = { [K in keyof T]: T[K] extends Array<infer R> ? FormArray< R extends Record<any, any> ? FormGroup<TypedFormControls<R>> : FormControl<R | null> > : T[K] extends Record<any, any> ? FormGroup<TypedFormControls<T[K]>> : FormControl<T[K] | null>; };
关键修改说明
- 去掉
[K in keyof T]-?:中的-?:该修饰符原本会移除所有属性的可选标记,现在保留原模型的可选属性特性,模型中带?的属性在表单类型中依然是可选的。 - 添加
| null:Angular表单控件默认支持空值,为控件类型加上null可以避免类型不匹配问题。
修改后的表单构建代码
现在你可以自由省略模型中的可选属性对应的表单控件,TypeScript不会再报错:
this.formGroup = this._formBuilder.group<TypedFormControls<UserModel>>({ email: this._formBuilder.control('email@email'), // 可选属性age可以省略 information: this._formBuilder.group<TypedFormControls<Information>>({ id: this._formBuilder.control(1), name: this._formBuilder.control('John'), // 可选属性gender可以省略 }), });
模型类(无需修改)
export class UserModel { email: string; age?: number; information?: Information; } export class Information { id: number; name: string; gender?: string; }
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

