fixed-length array with optional items in Typescript interface
Angular在其FormBuilder类中引入了模型驱动的表单,其主要方法
1 2 3 | group(controlsConfig: { [key: string]: any; }): FormGroup; |
1 2 3 4 5 | [ initial value of model's property, sync validator(s), async validator(s) ] |
仅需要第一个元素的地方。
我决定要比该类型强一点的类型,特别是在与强类型模型相关的任何东西上,因此我用T重新定义该函数:
1 2 3 4 5 | declare interface FormBuilder2 extends FormBuilder { group< T >(controlsConfig: { [K in keyof T]?: [T[K], ValidatorFn | ValidatorFn[] | null, ValidatorFn | ValidatorFn[] | null]; }): FormGroup; } |
这也意味着我在HTML中的所有formControlNames(当然也在group()调用中)都必须与模型的属性匹配,这是我更喜欢的。
似乎有效,但要满足以下条件:
1 2 3 4 5 | this.optionsForm = this.formBuilder2.group<CustomerModel>({ status: [this.model.status, [Validators.required], null], lastOrder: [this.model.lastOrder, null, null], comments: [this.model.comments, null, null], }); |
我必须在未使用的阵列插槽上提供
有没有一种方法可以使Typescript忽略对多余的
对于元组类型,没有真正的类型安全的方法,因为元组可以接受额外的元素。也就是说,例如,元组类型
但是,有解决方案! (请参阅下面的尝试3)
(顺便说一句,您忽略了Angular为异步验证器提供了一个不同的接口:
尝试1:
1 | [K in keyof T]?: [T[K] | ValidatorFn | ValidatorFn[] | null]; |
几乎不比
尝试2:
1 2 3 4 | [K in keyof T]?: [T[K]] | [T[K], ValidatorFn | ValidatorFn[]] | [T[K], ValidatorFn | ValidatorFn[] | null, AsyncValidatorFn | AsyncValidatorFn[]]; |
乍一看似乎更好。但是问题是Typescript编译器只会在万不得已时抛出错误。因此它将接受以下内容:
1 | someStringField: ['hi', 'hello'] |
因为这符合
尝试3:
有一个更好的解决方案,令我惊讶的是。我在撰写此答案的过程中发现了这一点,同时在Typescript GitHub存储库上阅读了此问题。
1 2 3 4 5 | [K in keyof T]?: { 0: T[K]; 1?: ValidatorFn | ValidatorFn[]; 2?: AsyncValidatorFn | AsyncValidatorFn[]; }; |
这是对先前尝试的一种改进,因为前三个元素始终都经过正确的类型检查。
希望这能解决您的问题。