javascript - Kontroll av arraytyper fungerar inte i nästlade objekt
let test: number[] = [1, 2, 3, 'a'] // correctly fails
let test2 = {
demo: 1,
items: <number[]> ['a', 'b'], // correctly fails
}
let test3 = {
demo: 1,
items: <number[]> [1, 2, 3, 'a'], // why passes if there is string inside?
}
Sandlåda här
Varför går det igenom om det finns åtminstone en korrekt värdetyp, och tillåter att resten är fel? Hur kan man säkerställa att ALLA Array-värden i objektposten är av en viss typ?
Svar #1
Syntaxen för test är något annorlunda från det du använder jämfört med test2 och test3. Detta:
let test: number[] = [1, 2, 3, 'a']
annoterar typen av test: det kräver att test är number[]. Den array som tilldelas uppfyller inte den typen, så det misslyckas.
Dina andra och tredje exempel är något helt annat, vilket är typförsäkran. Typförsäkran med <> eller as innebär i princip att säga till TypeScript: "Jag vet vad jag gör, detta uttryck är av typen SomeType, även om typkontrollen inte kan avgöra det från sammanhanget."
För ett liknande exempel är följande tillåtet:
const something = localStorage.foobar as number;
eller, ekvivalent
const something = <number> localStorage.foobar;
även om localStorage inte har en foobar-egenskap som är ett nummer. (Egenskaper i local storage är antingen strängar eller funktioner) Med as och <> anger du typen, oavsett vad TS kan härleda, inte kontrollerar typen.
Det andra exemplet med test2 misslyckas med följande felmeddelande:
Konvertering av typen 'string[]' till typen 'number[]' kan vara ett misstag eftersom ingen av typerna överlappar tillräckligt med den andra. Om detta var avsiktligt, konvertera uttrycket till 'unknown' först.
Det misslyckas inte för att typen inte kan försäkras, utan för att de två typerna inte överlappar tillräckligt.
Testet test3 passerar eftersom Array<number | string> faktiskt har viss överlappning med Array<number>.
För att fixa det och få både test2 och test3 att misslyckas som önskat, gå tillbaka till den syntax du använder med det första exemplet, där du sätter typen efter ett kolon direkt efter variabelnamnet:
let test3: {
demo: number;
items: number[];
} = {
demo: 1,
items: [1, 2, 3, 'a'], // This fails - good!
}
så att TypeScripts typkontroll kommer att kontrollera det korrekt, och resultera i ett typfel, utan att göra någon typförsäkran.
