[javascript] 속성 ‘…’에는 이니셜 라이저가 없으며 생성자에 확실히 할당되지 않았습니다.

내 Angular 앱에는 구성 요소가 있습니다.

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);
  }
}

하지만 “만들다”속성에 실수가 있습니다. 나는 그것으로 무엇을 해야할지 모르겠다 …

잘못



답변

최신 버전의 TypeScript를 사용하고 있다고 생각합니다. 의 “Strict Class Initialization”섹션을 참조하십시오 link.

이 문제를 해결하는 방법에는 두 가지가 있습니다.

A. VSCode를 사용하는 경우 편집기에서 사용하는 TS 버전을 변경해야합니다.

B. 생성자 내부에서 선언 할 때 배열을 초기화합니다.

makes: any[] = [];

constructor(private makeService: MakeService) {
   // Initialization inside the constructor
   this.makes = [];
}


답변

그냥 이동 tsconfig.json 및 설정

"strictPropertyInitialization": false

컴파일 오류를 제거합니다.

그렇지 않으면 조금 성가신 모든 변수를 초기화해야합니다.


답변

TypeScript 2.7에는 생성자에서 모든 속성을 초기화해야하는 엄격한 클래스 검사가 포함되어 있기 때문입니다. 해결 방법은 !변수 이름에 접미사로 를 추가하는 것입니다.

makes!: any[];


답변

Angular 프로젝트를 엄격 모드로 컴파일하기 Property has no initializer and is not definitely assigned in the constructor위해 tsconfig.json파일에 일부 구성을 추가 할 때 메시지가 표시 될 수 있습니다.

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

실제로 컴파일러는 멤버 변수가 사용되기 전에 정의되지 않았다고 불평합니다.

컴파일 타임에 정의되지 않은 멤버 변수의 예는 @Input지시문이 있는 멤버 변수입니다 .

@Input() userId: string;

변수가 선택 사항 일 수 있음을 지정하여 컴파일러를 침묵시킬 수 있습니다.

@Input() userId?: string;

그러나 변수가 정의되지 않은 경우를 처리하고 다음과 같은 일부 명령문으로 소스 코드를 복잡하게 만들어야합니다.

if (this.userId) {
} else {
}

대신,이 멤버 변수의 값을 알면 시간 내에 정의됩니다. 즉, 사용되기 전에 정의되므로 컴파일러에게 정의되지 않는 것에 대해 걱정하지 않도록 할 수 있습니다.

이것을 컴파일러에 알리는 방법은 다음 ! definite assignment assertion과 같이 연산자 를 추가하는 것입니다.

@Input() userId!: string;

이제 컴파일러는이 변수가 컴파일 타임에 정의되지는 않았지만 런타임에 그리고 사용되기 전에 정의되어야 함을 이해합니다.

이제이 변수가 사용되기 전에 정의되었는지 확인하는 것은 응용 프로그램에 달려 있습니다.

추가 보호 기능으로 변수를 사용하기 전에 정의되고 있음을 확인할 수 있습니다.

변수가 정의되어 있다고 주장 할 수 있습니다. 즉, 필요한 입력 바인딩이 실제로 호출 컨텍스트에 의해 제공되었습니다.

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();
}

변수가 정의되었으므로 이제 변수를 사용할 수 있습니다.

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

참고 ngOnInit 메서드는 바인딩에 실제 입력이 제공되지 않은 경우에도 입력 바인딩 시도 후에 호출됩니다.

반면 ngOnChanges방법은 입력 바인딩 시도 후 불러에만 바인딩 제공 실제 입력되어 있었다.


답변

초기화하고 싶지 않은 경우 다음을 수행 할 수도 있습니다.

makes?: any[];


답변

--strictPropertyInitializationSajeetharan이 언급 한 기능 을 비활성화 하거나 초기화 요구 사항을 충족하려면 다음과 같이해야합니다.

makes: any[] = [];


답변

TypeScript 2.7.2부터 선언 시점에 할당되지 않은 경우 생성자에서 속성을 초기화해야합니다.

Vue에서 오는 경우 다음을 시도 할 수 있습니다.

  • "strictPropertyInitialization": truetsconfig.json에 추가

  • 비활성화하는 것이 만족스럽지 않다면 이것을 시도 할 수도 있습니다 makes: any[] | undefined. 이렇게하려면 null 확인 ( ?.) 연산자 를 사용하여 속성에 액세스해야합니다.this.makes?.length

  • 시도해 볼 수도 있습니다 makes!: any[];. 이것은 TS에게 값이 런타임에 할당된다는 것을 알려줍니다.