I am having issues using enums in form types.
the following code:
export enum Frequency {
DAILY = 'DAILY',
WEEKLY = 'WEEKLY',
MONTHLY = 'MONTHLY',
QUARTERLY = 'QUARTERLY',
HALF_YEARLY = 'HALF_YEARLY',
YEARLY = 'YEARLY',
}
export type MyForm = FormGroup <{
frequency: FormControl<Frequency>,
}>
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular ' VERSION.major;
public form: MyForm = new FormGroup({
frequency: new FormControl(Frequency.DAILY),
})
}
gives the error:
Type 'FormGroup<{ frequency: FormControl<Frequency.DAILY>; }>' is not assignable to type 'MyForm'.
Type 'FormControl<Frequency>' is not assignable to type 'FormControl<Frequency.DAILY>'.
Type 'Frequency' is not assignable to type 'Frequency.DAILY'.
stackblitz: https://stackblitz.com/edit/angular-ivy-qsb4nb?file=src/app/app.component.html,src/app/app.component.ts
CodePudding user response:
import { Component, VERSION } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
// DEFINE ENUMS
enum Frequency {
DAYLY,
MONTHLY,
YEARLY,
}
// INCLUDE THEM IN CONST OBJECT TYPE DEFINITION
export const periodMap: Record<Frequency, string> = {
[Frequency.DAYLY]: 'DAILY',
[Frequency.MONTHLY]: 'MONTHLY', // WE NEED THE TYPE OF THIS
[Frequency.YEARLY]: 'YEARLY',
};
export type MyForm = FormGroup<{
// THE MAGIC: ACCESS THE STRING TYPE IN THE periodMap such as 'MONTHLY'
frequency: FormControl<typeof periodMap[keyof typeof periodMap]>;
}>;
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular ' VERSION.major;
public form: MyForm = new FormGroup({
frequency: new FormControl(periodMap[Frequency.DAYLY]), // Frequency control has string type.
});
constructor() {}
}
stackblitz link for your convenience and for other people
CodePudding user response:
The problem is solved by removing FormGroup
from your type and moving it to the form
variable like this:
export type MyForm = {
frequency: FormControl<Frequency>;
};
public form: FormGroup<MyForm> = new FormGroup<MyForm>({
frequency: new FormControl(Frequency.DAILY),
});
The returned new FormGroup
doesn't need to be typed as a formGroup
as it is already defined as a new FormGroup
, you only need to type it's controls.
Here is a working example on stackblitz.