Daktilo yazısında “tip parametresine asla atanamaz” hatası nedir?


164

Kod:

const foo = (foo: string) => {
  const result = []
  result.push(foo)
}

Aşağıdaki TS hatasını alıyorum:

[ts] 'string' türündeki bağımsız değişken, 'never' türündeki parametreye atanamaz.

Neyi yanlış yapıyorum? Bu bir hata mı?

Yanıtlar:


256

Tek yapmanız gereken, resultdizinizi aşağıdaki gibi bir dize dizisi olarak tanımlamaktır :

const result : string[] = [];

Dizi türünü tanımlamadan, varsayılan olarak olacaktır never. Bu nedenle, bir dize eklemeye çalıştığınızda, bu bir tür uyuşmazlığıydı ve böylece gördüğünüz hatayı attı.


7
Bu bana tuhaf geliyor, neden varsayılan never[]? bunun için "HER ZAMAN boş olacak bir dizi" dışında bir kullanım var mı?
Vincent Buscarello

7
Tamamen katılıyorum, çünkü dürüst olmak gerekirse, bir dizi nevers'nin yararlı olacağı bir kullanım durumu düşünemiyorum . Ama içine bakarken çok iyi bilgiye sahip bu cevaba rastladım .
Tha'er M. Al-Ajlouni

9
Varsayılan tür "herhangi" olmamalı mı? Bir değişken ( let x;) bildirdiğinizde any, varsayılan olarak türdür . Hayır never.
Shachar Har-Shuv

1
Kesinlikle türü olmayan bir dizi olmasını beklenir any[]. Bu never[]işe yaramaz hale şaşırdı . Unintuitive. Cevap için teşekkürler. düzenleme: dilbilgisi
Igor Malyk

4
@VincentBuscarello Sanırım, böyle bir temerrütün ana noktası, her zaman dizilerine tür eklemek için yapmaktır; ancak hata mesajı kesinlikle yardımcı olmaz.
YakovL

30

Başka bir yol:

const result = [] as  any;

8
Aslında kullanmak anyiyi bir seçenek değildir, çünkü temelde herhangi bir TypeScript özelliğini kapatır. Bu geçici bir çözümdür ve çeşitli hatalara yol açabilir.
Tomek Buszewski

1
Evet. Ancak bazen özellikle üçüncü taraf kütüphanelerle çalışırken başka hiçbir şey işe
yaramaz

14

Bu kısa bir süre önce yaşanan bir gerileme ya da dizgideki garip bir davranış gibi görünüyor. Kodunuz varsa:

const result = []

Genellikle yazdığınız gibi ele alınır:

const result:any[] = []

ancak tsconfig dosyasında noImplicitAnyYANLIŞ ve strictNullChecks DOĞRU varsa, şu şekilde değerlendirilir:

const result:never[] = []

Bu davranış, IMHO tüm mantığa meydan okur. Boş denetimleri açmak bir dizinin giriş türlerini değiştirir? Ve sonra açmak noImplicitAnyaslında anyherhangi bir uyarı olmadan kullanımını geri yükler ??

Gerçekten bir diziniz olduğunda any, bunu ekstra kodla belirtmeniz gerekmez.


10

ReactJs Hook useState kullanırken aynı hatayla ReactJS statless işlevi vardı . Bir nesne dizisinin durumunu ayarlamak istedim, bu yüzden aşağıdaki yolu kullanırsam

const [items , setItems] = useState([]);

ve durumu şu şekilde güncelleyin:

 const item = { id : new Date().getTime() , text : 'New Text' };
 setItems([ item , ...items ]);

Hata alıyordum:

'{id: number; text: any} ',' never 'türündeki parametreye atanamaz

ama eğer böyle yaparsa,

const [items , setItems] = useState([{}]);

Hata gitti, ancak 0 dizininde veri içermeyen bir öğe var (bunu istemiyorum).

böylece bulduğum çözüm:

const [items , setItems] = useState([] as any);

7

ReactJS useState kanca kullanarak ReactJS işlev bileşeninde aynı hatayı aldım. Çözüm, kullanım türünü bildirmekti Başlangıçta durum:

const [items , setItems] = useState<IItem[]>([]); // replace IItem[] with your own typing: string, boolean...

3

Boş parantez yerine Array anahtar sözcüğünü kullanarak bunu aşabildim:

const enhancers: Array<any> = [];

kullanın:

if (typeof devToolsExtension === 'function') {
  enhancers.push(devToolsExtension())
}

2

Bir resultdize dizisine yazmanız gerekir const result: string[] = [];.



1

Kaldır doğrudur: "strictNullChecks" dan "compileroptions" veya false olarak ayarlayın tsconfig.json sizin Ng app dosyası. Bu hatalar her şey gibi gider ve uygulamanız başarıyla derlenir.

Feragatname : Bu sadece bir çözümdür. Bu hata, yalnızca boş denetimler düzgün bir şekilde ele alınmadığında ortaya çıkar; bu, her durumda işleri halletmek için iyi bir yol değildir.

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.