网站搜索

typescript - 如何定义 Angular FormGroup 的子集?


考虑这个例子:

我有一个 form1 和 form2,它们都有多个 FormControl,但它们共享一个公共的 FormControl id

现在,我想将这个表单作为参数传递给一个方法,而该方法只应该了解 id 属性。

我如何为 myMethod() 的参数添加类型提示?我想确保 myMethod 的参数是一个包含名为 id 的 FormControl 的 FormGroup,但可以包含其他任意(可选的)FormControls。我尝试过 FormGroup<{id: FormControl}>,但这行不通。错误信息是:

TS2345: Argument of type 'FormGroup<{ id: FormControl<any>; name: FormControl<any>; }>' is not assignable to parameter of type 'FormGroup<{ id: FormControl<any>; }>'.
Property 'name' is missing in type '{ id: FormControl<any>; }' but required in type '{ id: FormControl<any>; name: FormControl<any>; }'.

用正确的方式如何为只包含 id 的 form 提供类型提示?

export class AppComponent {
  readonly form1 = new FormGroup({
    id: new FormControl(),
    name: new FormControl(),
  });
  readonly form2 = new FormGroup({
    id: new FormControl(),
    title: new FormControl(),
  });

  ngOnInit(): void {
    this.myMethod(this.form1); // Throws error
    this.myMethod(this.form2); // Throws error
  }

  myMethod(form: FormGroup<{id: FormControl}>) {
    // do something
  }
}

答案#1

使用 AbstractControl

method(control:AbstractControl)
{
    console.log(control.get('id').value)

    //you can also "cast" to formGroup
    const formGroup=control as FormGroup

}

答案#2

有几种方法,但并非所有方法似乎都是同等有效的。

1. 映射类型

我偏好的方法是这样的:

myMethod(form: MyForm) {
  const id = form.controls.id //works.
}

interface MyForm extends FormGroup<{id: FormControl}> {
  [key: string]: any;
}

它很不错,简单,可读,并且适用于大多数情况。它或多或少地表示:“我们正在使用一个 FormGroup<{id: FormControl}>,顺便说一下,它可能还有一堆我们不关心的其他东西。”

2. 部分

如果你想要一个简单的一行代码,它可以在 form.controls.id 上提供自动完成功能,并且不会报错,这个方法……也相当有效。不过它没有完整的类型安全,因为所有属性都被视为可选,这可能会是个问题,因此除非你需要快速且粗糙的解决方案,否则我不推荐使用它。

myMethod(form: Partial<FormGroup<{id: FormControl}>>) {
   const id = form.controls.id //works.
}

//Examples:
myMethod('test') // Doesn't work, because it has nothing at all in common with FormGroup<{id: FormControl}>
myMethod({valid:true}) // Works, because all parameters are optional and it has at LEAST one property that FormGroup<{id: FormControl}> has.