funktionell programmering - Varför härleder TypeScript typen 'never' när man reducerar en Array med concat?
Kod talar bättre än språk, så:
['a', 'b', 'c'].reduce((accumulator, value) => accumulator.concat(value), []);
Koden är väldigt fånig och returnerar en kopierad array...
TS klagar på concat's argument: TS2345: Argument av typen 'string' kan inte tilldelas parametern av typen 'ConcatArray'.
Svar #1
Jag tror att detta beror på att typen för [] antas vara never[], vilket är typen för en array som MÅSTE vara tom. Du kan använda en typomvandling för att åtgärda detta:
['a', 'b', 'c'].reduce((accumulator, value) => accumulator.concat(value), [] as string[]);
Normalt skulle detta inte vara något större problem eftersom TypeScript gör ett ganska bra jobb med att lista ut en bättre typ att tilldela en tom array baserat på vad du gör med den. Men eftersom ditt exempel är 'löjligt' som du uttryckte det, kan TypeScript inte göra några slutledningar och lämnar typen som never[].
Svar #2
En bättre lösning som undviker en typavstämning (även kallad typomvandling) i två varianter:
- Använd
string[]som den generiska typparametern förreduce-metoden (tack @depoulo för att du nämnde det):
['a', 'b', 'c'].reduce<string[]>((accumulator, value) => accumulator.concat(value), []);
- Skriv in
accumulator-värdet somstring[](och undvik en typkonvertering på[]):
['a', 'b', 'c'].reduce((accumulator: string[], value) => accumulator.concat(value), []);
Lek med denna lösning i TypeScript-lekplatsen.
Anteckningar:
Typpåståenden (ibland kallade typomvandlingar) borde undvikas om du kan eftersom du tar en typ och överför den på något annat. Detta kan orsaka bieffekter eftersom du manuellt tar kontroll över att tvinga en variabel till en annan typ.
Detta Typescript-fel uppstår endast om
strictNullChecks-alternativet är inställt påtrue. Typescript-felet försvinner när du stänger av det alternativet, men det är förmodligen inte vad du vill.Jag refererar till hela felmeddelandet jag får med Typescript
3.9.2här så att Google hittar denna tråd för personer som söker svar (eftersom Typescript-felmeddelanden ibland ändras från version till version):No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error. Argument of type 'string' is not assignable to parameter of type 'ConcatArray<never>'. Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error. Argument of type 'string' is not assignable to parameter of type 'ConcatArray<never>'.(2769)
