angular 为FormRecord添加键入的键

iyr7buue  于 4个月前  发布在  Angular
关注(0)|答案(1)|浏览(38)

与功能请求相关的@angular/*包有哪些?

forms

描述

目前,FormRecord 只支持输入控件,但不支持按键:

new FormRecord<FormControl<boolean>>({
  key1: new FormControl(false, { nonNullable: true }),
  key2: new FormControl(false, { nonNullable: true }),
  key3: new FormControl(false, { nonNullable: true }),
});

在这里,控件只能是FormControl<boolean>,但控件的键可以是任何字符串(只要是字符串)。
但是在某些情况下,我们希望键被限制为特定的字符串集合(或枚举)。

enum ControlKey {
  Key1 = 'key1',
  Key2 = 'key2',
  Key3 = 'key3',
}

new FormRecord<FormControl<boolean>>({
  key1: new FormControl(false, { nonNullable: true }),
  key2: new FormControl(false, { nonNullable: true }),
  key4: new FormControl(false, { nonNullable: true }), // I want the "key4" to throw a typing error here
});

这对于我们可以通过表单激活/停用已知选项列表非常有用。
这个主题已经在这里有讨论过:

  • feat(forms):添加一个FormRecord类型。#45607(评论)
  • [完成] RFC:严格类型的响应式表单#44513(评论)

但它看起来从未被考虑作为新功能。

建议的解决方案

我们可以更新FormRecord的类型,使用类似这样的东西:

export class FormRecord<
  TControl extends AbstractControl = AbstractControl,
  TKey extends string = string
> extends FormGroup<Partial<Record<TKey, TControl>>> {}

export interface FormRecord<TControl, TKey> {
  registerControl(name: TKey, control: TControl): TControl;
  addControl(name: TKey, control: TControl, options?: { emitEvent?: boolean }): void;
  removeControl(name: TKey, options?: { emitEvent?: boolean }): void;
  setControl(name: TKey, control: TControl, options?: { emitEvent?: boolean }): void;
  contains(controlName: TKey): boolean;
  setValue(value: Partial<Record<TKey, ɵValue<TControl>>>, options?: { onlySelf?: boolean, emitEvent?: boolean }): void;
  patchValue(value: Partial<Record<TKey, ɵValue<TControl>>>, options?: { onlySelf?: boolean, emitEvent?: boolean }): void;
  reset(value?: Partial<Record<TKey, ɵValue<TControl>>>, options?: { onlySelf?: boolean, emitEvent?: boolean }): void;
  getRawValue(): Partial<Record<TKey, ɵValue<TControl>>>;
}

这样我们就可以像这样使用它:

enum ControlKey {
  Key1 = 'key1',
  Key2 = 'key2',
  Key3 = 'key3',
}

const form = new FormRecord<FormControl<boolean>, ControlKey>({
  [ControlKey.Key1]: new FormControl(false, { nonNullable: true }),
  [ControlKey.Key2]: new FormControl(false, { nonNullable: true }),
  [ControlKey.Key3]: new FormControl(false, { nonNullable: true }),
});

考虑过的替代方案

目前我正在使用一个FormGroup来满足我的需求:

enum ControlKey {
  Key1 = 'key1',
  Key2 = 'key2',
  Key3 = 'key3',
}

new FormGroup<Partial<Record<ControlKey, FormControl<boolean>>>>({
  [ControlKey.Key1]: new FormControl(false, { nonNullable: true }),
  [ControlKey.Key2]: new FormControl(false, { nonNullable: true }),
  [ControlKey.Key3]: new FormControl(false, { nonNullable: true }),
});
wljmcqd8

wljmcqd81#

我已经提议在引入 FormRecord 时使用 FormGroupRecord<key, value> m,所以我支持这个实现。

相关问题