Hur man får funktioner att behandla returvärdet av (A | B)[] och A[] | B[] som ekvivalent i TypeScript
Det verkar som att typerna (A | B)[] och A[] | B[] är ekvivalenta i TypeScript. Detta kan bekräftas genom följande:
var test1: number[] | string[] = [1]
var test2: (number | string)[] = ["stuff"]
var test3: (number | string)[] = test1
Men det verkar som att detta faller isär när dessa typer dyker upp i returfunktioner. Detta illustreras nedan:
function getStuff(flag:number): number | string {
if (flag == 0) {
return 1
} else {
return "hello"
}
}
function returnStuff(flag: number): number[] | string[] {
let toReturn: (number | string)[] = [getStuff(flag)]
// toReturn is of type (number | string)[] but trying to return it when the return type
// is number[] | string[] fails even though they should be equivalent
return toReturn;
}
Jag har då två frågor:
- Vad är anledningen till detta beteende och hur kan det åtgärdas för att få önskat beteende?
- Finns det någon typnivåmaskineri i TS som kan användas för att konvertera mellan
number[] | string[]och(number | string)[]
Svar #1
Vad är orsaken bakom detta beteende
nummer[] | sträng[]
du har två möjliga arrayer, en array som endast innehåller siffror, och en array som endast innehåller strängar
[1,2,3,4] //valid
["foo", "bar"] //valid
[1,2,"foobar"] //this is invalid
(nummer | sträng)[]
Du har en möjlig array som innehåller antingen ett nummer eller en sträng.
[1,2,3,4] //valid
["foo", "bar"] //valid
[1,2,"foobar",3,"lorem"] //valid
I den här är den viktigaste punkten att komma ihåg att arrayen kan innehålla ett element som är av typen sträng ELLER nummer, oavsett om alla element i arrayen är av samma typ eller inte
Finns det någon typnivåmaskineri i TS som kan användas för att konvertera mellan number[] | string[] och (number | string)[]
Du kan fortfarande använda din string[] eller number[] som (string | number)[]
let x: number[] = [1,2,3,4]
return x as (number | string)[]
