La propiedad '...' no tiene inicializador y no está definitivamente asignada en el constructor

104

en mi aplicación Angular tengo un componente:

import { MakeService } from './../../services/make.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-vehicle-form',
  templateUrl: './vehicle-form.component.html',
  styleUrls: ['./vehicle-form.component.css']
})
export class VehicleFormComponent implements OnInit {
  makes: any[];
  vehicle = {};

  constructor(private makeService: MakeService) { }

  ngOnInit() {
    this.makeService.getMakes().subscribe(makes => { this.makes = makes
      console.log("MAKES", this.makes);
    });
  }

  onMakeChange(){
    console.log("VEHICLE", this.vehicle);
  }
}

pero en la propiedad "hace" tengo un error. No sé qué hacer con eso ...

Error

Michael Kostiuchenko
fuente

Respuestas:

59

Creo que está utilizando la última versión de TypeScript. Consulte la sección "Inicialización estricta de clases" en el link.

Hay dos formas de solucionar este problema:

R. Si está usando VSCode, necesita cambiar la versión de TS que usa el editor.

B. Simplemente inicialice la matriz cuando la declare dentro del constructor,

makes: any[] = [];

constructor(private makeService: MakeService) { 
   // Initialization inside the constructor
   this.makes = [];
}
Sajeetharan
fuente
lo siento, soy nuevo en mecanografiado. ¿Puedes decir dónde está mi error?
Michael Kostiuchenko
2
como dice el error, es necesario inicializar la variable a algún valor hace: any [] = [];
Sajeetharan
158

Simplemente vaya a tsconfig.json y configure

"strictPropertyInitialization": false

para deshacerse del error de compilación.

De lo contrario, debe inicializar todas sus variables, lo cual es un poco molesto

Martin Čuka
fuente
3
Solo asegúrese de agregar eso después de "estricto": verdadero, de lo contrario, el transpilador parece encenderlo nuevamente (aunque VS parece saber que está apagado).
lunes
35
De esta manera, deshabilitará la inicialización de la propiedad de verificación estricta para todo el proyecto. Es mejor agregar el !operador de sufijo al nombre de la variable, simplemente ignorar este caso, o inicializar la variable dentro del constructor.
Matteo Guarnerio
6
Está sugiriendo ignorar los problemas potenciales que el compilador está informando, esto no es realmente seguro. Así que vota en contra.
Olga
6
StrictPropertyInitialzer es una marca introducida en el mecanografiado 2.7. Depende de todos elegir si desea habilitar todas estas banderas y seguir estrictamente todas las reglas o desactivar alguna validación. No tiene ningún sentido seguir todas las reglas todo el tiempo. Si su código se vuelve demasiado detallado y tiene desventajas y son más grandes que las ventajas, definitivamente debe desactivarlo. No estoy diciendo que esta sea la mejor práctica en todos los casos, pero es definitivamente una opción viable en la mayoría de los casos ...
Martin Čuka
1
Como mencioné en mi respuesta, tiene dos opciones: deshabilita la validación O inicializa todas las variables. Depende de todos elegir qué se beneficiará más de un proyecto a otro.
Martin Čuka
46

Esto se debe a que TypeScript 2.7 incluye una comprobación de clase estricta donde todas las propiedades deben inicializarse en el constructor. Una solución es agregar !como sufijo al nombre de la variable:

makes!: any[];
Harinath
fuente
11
Los "!" La sintaxis existe para aquellos casos comunes en los que no puede garantizar que el valor se defina inmediatamente. Es una trampilla de escape y no se debe confiar en ella, ya que puede hacer que su código sea menos seguro. Por lo general, se prefiere un valor predeterminado. Sin embargo, es bueno saber que existe
kingdaro
@kingdaro tiene razón. Si bien esto generalmente se puede usar, también puede conducir a un código que no funciona. Como ejemplo, en la aplicación web básica generada por VS2017, cambie la asignación de los pronósticos en fetchdata.components.ts agregando el '!' (¡pronósticos públicos !: WeatherForecast [];) y provocará un error completo
IronRod
14

Es posible que recibamos el mensaje Property has no initializer and is not definitely assigned in the constructoral agregar alguna configuración en el tsconfig.jsonarchivo para tener un proyecto Angular compilado en modo estricto:

"compilerOptions": {
  "strict": true,
  "noImplicitAny": true,
  "noImplicitThis": true,
  "alwaysStrict": true,
  "strictNullChecks": true,
  "strictFunctionTypes": true,
  "strictPropertyInitialization": true,

De hecho, el compilador luego se queja de que una variable miembro no está definida antes de ser utilizada.

Para un ejemplo de una variable miembro que no está definida en tiempo de compilación, una variable miembro que tiene una @Inputdirectiva:

@Input() userId: string;

Podríamos silenciar el compilador indicando que la variable puede ser opcional:

@Input() userId?: string;

Pero entonces, tendríamos que lidiar con el caso de que la variable no esté definida y saturar el código fuente con algunas de estas declaraciones:

if (this.userId) {
} else {
}

En cambio, conociendo el valor de esta variable miembro se definiría en el tiempo, es decir, se definiría antes de ser utilizada, podemos decirle al compilador que no se preocupe por no estar definida.

La forma de decirle esto al compilador es agregar el ! definite assignment assertionoperador, como en:

@Input() userId!: string;

Ahora, el compilador entiende que esta variable, aunque no está definida en tiempo de compilación, se definirá en tiempo de ejecución y en el tiempo, antes de que se utilice.

Ahora depende de la aplicación asegurarse de que esta variable esté definida antes de ser utilizada.

Como protección adicional, podemos afirmar que la variable se está definiendo, antes de usarla.

Podemos afirmar que la variable está definida, es decir, el contexto de llamada proporcionó el enlace de entrada requerido:

private assertInputsProvided(): void {
  if (!this.userId) {
    throw (new Error("The required input [userId] was not provided"));
  }
}

public ngOnInit(): void {
  // Ensure the input bindings are actually provided at run-time
  this.assertInputsProvided();
}

Sabiendo que se definió la variable, la variable ahora se puede usar:

ngOnChanges() {
  this.userService.get(this.userId)
    .subscribe(user => {
      this.update(user.confirmedEmail);
    });
}

Tenga en cuenta que el ngOnInitmétodo se llama después del intento de vinculación de entrada, esto, incluso si no se proporcionó una entrada real a las vinculaciones.

Mientras que el ngOnChangesmétodo se llama después del intento de vinculación de entrada, y solo si se proporcionó una entrada real a las vinculaciones.

Stephane
fuente
esta es la respuesta correcta cuando se usa el modo 'estricto'
RnDrx
8

--strictPropertyInitializationDebe desactivar el al que se refirió Sajeetharan, o hacer algo como esto para satisfacer el requisito de inicialización:

makes: any[] = [];
kshetline
fuente
5

También puede hacer lo siguiente si realmente no desea inicializarlo.

makes?: any[];
SpeedOfSpin
fuente
4

Cuando actualiza usando [email protected], su compilador sigue estrictamente las reglas para el tipo de matriz declare dentro del constructor de la clase del componente.

Para solucionar este problema, cambie el código donde se declaran en el código o evite que el compilador agregue la propiedad "strictPropertyInitialization": false en el archivo "tsconfig.json" y vuelva a ejecutar npm start.

Desarrollo de aplicaciones móviles y web angulares puede ir a www.jtechweb.in

Jai Govind Gupta
fuente
4

A partir de TypeScript 2.7.2, debe inicializar una propiedad en el constructor si no se asignó en el momento de la declaración.

Si viene de Vue, puede probar lo siguiente:

  • Agregue "strictPropertyInitialization": truea su tsconfig.json

  • Si no está satisfecho con la desactivación, también puede intentar esto makes: any[] | undefined. Hacer esto requiere que acceda a las propiedades con el ?.operador check ( ) nulo , es decirthis.makes?.length

  • También podría intentarlo makes!: any[];, esto le dice a TS que el valor se asignará en tiempo de ejecución.
codejockie
fuente