Angular中严格类型表单联合类型收窄问题求助
泛型基表单类的TypeScript类型错误问题及解决
我有三个核心数据相同、仅个别属性不同的表单实例,想要创建一个接收泛型参数的基表单类,以此收窄类型并移除不需要的控件,但和TypeScript僵持了数小时,差点要放弃转而使用无类型表单。
简化示例代码
export type FormOne = { name: AbstractControl<string | null>; email: AbstractControl<string | null>; age: AbstractControl<number | null>; }; export type FormTwo = { name: AbstractControl<string | null>; email: AbstractControl<string | null>; }; export type FormThree = { name: AbstractControl<string | null>; email: AbstractControl<string | null>; location: AbstractControl<string | null>; }; export type BaseForm = FormOne | FormTwo | FormThree;
尝试定义的基类
@Directive() export abstract class BaseFormComponent<T extends BaseForm> { private readonly _formBuilder = inject(FormBuilder); public readonly baseForm = this._formBuilder.group<T>({ name: this._formBuilder.control<string | null>(''), email: this._formBuilder.control<string | null>(''), age: this._formBuilder.control<number | null>(0), location: this._formBuilder.control<string | null>(''), }); }
遇到的TS2345错误
TS2345: Argument of type { name: FormControl<string | null>; email: FormControl<string | null>; age: FormControl<number | null>; location: FormControl<string | null>; } is not assignable to parameter of type T { name: FormControl<string | null>; email: FormControl<string | null>; age: FormControl<number | null>; location: FormControl<string | null>; } is assignable to the constraint of type T, but T could be instantiated with a different subtype of constraint BaseForm.
我对此感到困惑,因为BaseForm只有我定义的三个子类型,我理解联合类型BaseForm会被解析为:
{ name: AbstractControl<string | null>; email: AbstractControl<string | null>; age?: AbstractControl<number | null>; location?: AbstractControl<string | null>; }
按道理这应该允许我在抽象类中定义的基础表单结构。
最终目标组件
@Component({...}) export class FormTwoComponent extends BaseFormComponent<FormTwo> implements OnInit { public ngOnInit(): void { this.baseForm.removeControl('age'); this.baseForm.removeControl('location'); } }
我知道上述组件在ngOnInit执行前,表单并不符合给定的T类型,可能会导致编译时问题,但现在连基类都定义不成功。恳请精通TypeScript的人解释我哪里出错了,以及是否有可行的解决方法?
内容的提问来源于stack exchange,提问作者Alex Davis
相关产品推荐
相关产品推荐

