'…' Özelliğinin başlatıcısı yoktur ve yapıcıda kesinlikle atanmamış


105

Angular uygulamamda bir bileşenim var:

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

ama "yapar" özelliğinde bir hata var. Onunla ne yapacağımı bilmiyorum ...

hata

Yanıtlar:


62

TypeScript'in en son sürümünü kullandığınızı düşünüyorum. Lütfen "Katı Sınıf Başlatma" bölümüne bakın link.

Bunu düzeltmenin iki yolu vardır:

A. VSCode kullanıyorsanız, düzenleyicinin kullandığı TS sürümünü değiştirmeniz gerekir.

B. Diziyi yapıcı içinde ilan ettiğinizde başlatın,

makes: any[] = [];

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

üzgünüm, daktilo konusunda yeniyim. Hatam nerede diyebilir misin?
Michael Kostiuchenko

2
hata, değişkeni bir değerle başlatmanız gerektiğini söylediği gibi: any [] = [];
Sajeetharan

163

Tsconfig.json'a gidin ve

"strictPropertyInitialization": false

derleme hatasından kurtulmak için.

Aksi takdirde, biraz can sıkıcı olan tüm değişkenlerinizi başlatmanız gerekir.


3
Bunu "katı" dan sonra eklediğinizden emin olun: true, aksi takdirde aktarıcı tekrar açıyor gibi görünür (VS'nin kapalı olduğunu biliyor gibi görünmesine rağmen).
Monty

35
Bu şekilde, tüm proje için sıkı kontrol özelliği başlatmayı devre dışı bırakacaksınız. !Sonek operatörünü değişken adına eklemek, bu durumu yok saymak veya değişkeni yapıcı içinde başlatmak daha iyidir .
Matteo Guarnerio

6
Derleyicinin anlattığı olası sorunları görmezden gelmenizi öneriyorsunuz, bu gerçekten güvenli değil. Yani olumsuz oy.
Olga

6
StrictPropertyInitialzer, typcript 2.7'de sunulan bir bayraktır. Tüm bu bayrakları etkinleştirmek ve kesinlikle tüm kurallara uymak veya bazı doğrulamaları kapatmak isteyip istemediğinize karar vermek herkese bağlıdır. Her seferinde tüm kurallara uymanın hiçbir anlamı yok. Kodunuz çok ayrıntılı ve dezavantajlı hale gelirse ve avantajlardan daha büyükse, kesinlikle onu kapatmalısınız. Bunun her durumda en iyi uygulama olduğunu söylemiyorum, ancak çoğu durumda kesinlikle geçerli bir seçenek ...
Martin Čuka

1
Cevabımda bahsettiğim gibi, iki seçeneğiniz var ya doğrulamayı devre dışı bırakın VEYA tüm değişkenleri başlatın. Projeden projeye neyin daha fazla yararlanacağını seçmek herkese bağlıdır.
Martin Čuka

49

Bunun nedeni, TypeScript 2.7'nin tüm özelliklerin yapıcıda başlatılması gereken katı bir sınıf denetimi içermesidir. Geçici bir çözüm, !değişken adına sonek olarak eklemektir :

makes!: any[];

12
"!" sözdizimi, değerin hemen tanımlanacağını garanti edemeyeceğiniz yaygın durumlar için mevcuttur. Bu bir kaçış kapısıdır ve kodunuzu daha az güvenli hale getirebileceği için güvenilmemelidir. Genellikle varsayılan bir değer tercih edilir.
Var

@kingdaro haklı. Bu genellikle kullanılabilirken, düzün çalışmadığı bir koda da yol açabilir. Örnek olarak, VS2017 tarafından oluşturulan temel web uygulamasında, fetchdata.components.ts'deki tahminlerin atamasını '!' (genel tahminler !: WeatherForecast [];) ve tamamen hata yapmasına neden olacak
IronRod

14

Bir Angular projesinin katı modda derlenmesi Property has no initializer and is not definitely assigned in the constructoriçin tsconfig.jsondosyaya bazı konfigürasyonlar eklerken mesajı alabiliriz :

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

Aslında derleyici daha sonra bir üye değişkenin kullanılmadan önce tanımlanmadığından şikayet eder.

Derleme zamanında tanımlanmamış bir üye değişken örneği için, bir @Inputdirektif içeren bir üye değişkeni :

@Input() userId: string;

Değişkenin isteğe bağlı olabileceğini belirterek derleyiciyi susturabiliriz:

@Input() userId?: string;

Ama sonra, değişkenin tanımlanmamış olması durumuyla ilgilenmemiz ve kaynak kodunu bu tür ifadelerle karıştırmamız gerekir:

if (this.userId) {
} else {
}

Bunun yerine, bu üye değişkenin değerini bilmek zamanında tanımlanacaktır, yani kullanılmadan önce tanımlanacaktır, derleyiciye tanımlanmaması konusunda endişelenmemesini söyleyebiliriz.

Bunu derleyiciye söylemenin yolu ! definite assignment assertion, aşağıdaki gibi operatörü eklemektir :

@Input() userId!: string;

Şimdi, derleyici bu değişkenin, derleme zamanında tanımlanmamış olmasına rağmen, çalışma zamanında ve kullanılmadan önce zamanında tanımlanması gerektiğini anlar.

Bu değişkenin kullanılmadan önce tanımlanmasını sağlamak artık uygulamaya bağlıdır.

Ek bir koruma olarak, kullanmadan önce değişkenin tanımlandığını söyleyebiliriz.

Değişkenin tanımlandığını, yani gerekli girdi bağlamanın aslında çağıran bağlam tarafından sağlandığını iddia edebiliriz:

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

Değişkenin tanımlandığını bilerek, değişken artık kullanılabilir:

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

ngOnInitYöntemin giriş bağlama girişiminden sonra çağrıldığına dikkat edin , bu, bağlamalara hiçbir gerçek girdi sağlanmasa bile.

Oysa ngOnChangesyöntemi giriş bağlantıları çalışıldıktan sonra denir ve sadece bağları sağlanan gerçek giriş orada edilir.


bu 'katı' modu kullanırken doğru cevap
RnDrx

9

--strictPropertyInitializationBaşlatma gereksinimini karşılamak için ya Sajeetharan'ın bahsettiği şeyi devre dışı bırakmanız ya da buna benzer bir şey yapmanız gerekir:

makes: any[] = [];

6

Bunu gerçekten başlatmak istemiyorsanız, aşağıdakileri de yapabilirsiniz.

makes?: any[];

5

TypeScript 2.7.2'den itibaren, bildirim noktasında atanmamışsa, yapıcıdaki bir özelliği başlatmanız gerekir.

Vue'dan geliyorsanız, şunları deneyebilirsiniz:

  • "strictPropertyInitialization": trueTsconfig.json dosyanıza ekleyin

  • Devre dışı bırakmaktan memnun değilseniz, bunu da deneyebilirsiniz makes: any[] | undefined. Bunu yapmak, özelliklere null check ( ?.) operatörüyle erişmenizi gerektirir, örn.this.makes?.length

  • Deneyebilirsiniz makes!: any[];, bu TS'ye değerin çalışma zamanında atanacağını söyler.

3

Typescript@2.9.2 kullanarak yükselttiğinizde, derleyicisi, bileşen sınıfı yapıcısı içinde dizi türü bildirimi için katı kurallar izler.

Bu sorunu düzeltmek için ya kodda bildirilen kodu değiştirin ya da "tsconfig.json" dosyasına "tightPropertyInitialization": false özelliğini eklemek için derleyiciden kaçının ve npm start'ı yeniden çalıştırın.

Angular web ve mobil Uygulama Geliştirme www.jtechweb.in adresine gidebilirsiniz


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.