Типизированная форма в Angular 14 показывает `<any>` вместо типов

Находясь в последней версии 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.

  • Пример:

Типизированная форма в Angular 14 показывает `&lt;any&gt;` вместо типов

  • package.json

Типизированная форма в Angular 14 показывает `&lt;any&gt;` вместо типов

  • Официальная документация по Angular:

https://angular.io/guide/typed-forms

🤔 А знаете ли вы, что...
Angular поддерживает локализацию и многоязычность приложений.


521
2

Ответы:

Решено
TL;DR: то, как TypeScript идентифицирует свои «типы», в основном из-за интерфейсов и контекста. Чтобы решить, используйте явный интерфейс и передайте его в форму, поскольку его нельзя вывести.

Вы можете проверить как работает вывод типов для более подробной информации в 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],
  });
}

Интересные вопросы для изучения

Ошибка: эта команда недоступна при запуске Angular CLI вне рабочей областиУстановка начальной загрузки в angular 14 не удаласьКак устранить ошибку ngx-bootstrap в Angular-14Как разрешить конфликты зависимостей одноранговых узлов с помощью Nx, Angular и Nest?Не могу заполнить таблицу из JSON в angular и ошибки нетОшибка машинописного текста: элемент неявно имеет тип «любой», поскольку выражение типа «строка» не может использоваться для типа индексаПочему в TypeScript пустой массив выводится как «любой []», когда значение noImplicitAny равно true, и выводится как «никогда []», когда оно ложно?Как протестировать ввод с помощью библиотеки тестирования React?Jest collectCoverageFrom и CoverageThreshold не работаетКак исправить «Возможно, вам понадобится соответствующий загрузчик для обработки этого типа файла, в настоящее время загрузчики не настроены для обработки этого файла»