Находясь в последней версии Angular (версия 14), кажется, что я что-то не так делаю, и поэтому реактивные формы строго типизированный не работают должным образом.
Форма инициализируется внутри ngOnInit
с помощью инжекта FormBuilder
.
public form!: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.initializeForm();
}
private initializeForm(): void {
this.form = this.formBuilder.group({
title: ['', [Validators.required, Validators.minLength(3)]],
content: ['', Validators.required],
});
}
Теперь, когда я пытаюсь получить доступ к элементам управления формы, автозаполнение отсутствует, а тип — FormGroup<any>
. Также он не выдает ошибку при попытке доступа к элементам управления, которых нет в объекте FormGroup
.
package.json
https://angular.io/guide/typed-forms
🤔 А знаете ли вы, что...
Angular поддерживает локализацию и многоязычность приложений.
Вы можете проверить как работает вывод типов для более подробной информации в typescriptlang, вот небольшая выдержка:
Простой тип let x = 4
быть number
The type of the x variable is inferred to be number. The kind of inference takes place when initializing variables and members, setting parameter default values, and determining function return types.
Лучший распространенный тип let x = [0, 1, null]
относится к типу (number | null)[]
To infer the type of x in the example above, we must consider the type of each array element. Here we are given two choices for the type of the array: number and null. The best common type algorithm considers each candidate type, and picks the type that is compatible with all the other candidates.
Контекстные типы window.onmousedown = function (mouseEvent) { ... }
, существо MouseEvent
Contextual typing applies in many cases. Common cases include arguments to function calls, right hand sides of assignments, type assertions, members of object and array literals, and return statements. The contextual type also acts as a candidate type in best common type.
Невозможно вывести тип form
, вы должны указать это явно. Я сделал этот рабочий пример машинописной формы. официальная документация, который вы включили в свой вопрос, уже дает вам большую часть ответа.
Чтобы удалить <any>
, который вы видите в своем автозаполнении, просто реализуйте свой собственный интерфейс:
export interface IMainForm {
title: FormControl<string>;
content: FormControl<string>;
}
public form!: FormGroup<IMainForm>; // <--- Use your interface
Кроме того, ваша реализация this.formBuilder.group
устарела, потому что не является типобезопасным. Вместо этого вам нужно будет использовать перегрузку с AbstractControlOptions
(а не с массивом).
private initializeForm(): void {
this.form = this.formBuilder.group({
title: new FormControl<string|null>(null, [Validators.required, Validators.minLength(3)]),
content: new FormControl<string|null>(null, Validators.required)
});
}
Как вы можете видеть на следующем изображении, с этими изменениями вы увидите введенное значение {Partial<{ title: string; content: string; }>}
.
Вот решение, которое не требует от вас определения интерфейса, но использует предполагаемый тип
form: ReturnType<typeof this.initializeForm>
...
private initializeForm() {
return this.formBuilder.group({
title: ['', [Validators.required, Validators.minLength(3)]],
content: ['', Validators.required],
});
}