Typescript typehåndhevelse
Jeg er ny på Typescript, og jeg er litt forvirret over hvorfor denne koden kompilerer korrekt. images er et Array av strenger, men this.data blir tildelt et objekt der images er et Objekt.
declare type vd = {
images: Array<string>;
}
class mytest {
data: vd;
constructor() {
let obj = ['hello!', 'bye'];
this.data = { images: { ...obj } };
console.log(this.data.images);
}
}
Som forventet, blir dette skrevet ut på konsollen:
Objekt 0: "hei!" 1: "ha det"
Å bytte ut krøllparentesene med vanlige parenteser, skriver ut følgende:
Array(2) 0: "hei!" 1: "ha det" length: 2
Hvorfor klager ikke kompilatoren på tildelingen av this.data i det første tilfellet?
Svar #1
I JavaScript og TypeScript er arrays objekter, så med din obj-variabel initialisert som array, er denne meningsløse operasjonen gyldig og tillatt - som Aluan Haddad sa i kommentaren, kan du spre en array (som er et objekt) inn i et objekt:
{...obj}
For å avsløre hvilken type den produserer, kan du legge til denne meningsløse tildelingen og se feilmeldingen:
const r: void = { ...obj }
Type '{ [n: number]: string; length: number; toString(): string; toLocaleString(): string; push(...item...' kan ikke tildeles typen 'void'.
Se, som et resultat av spread, ser typen av {...obj} akkurat ut som et array, den har indeksérbar etter tall-signatur, og den har alle egenskaper og metoder som et array har, så, etter TypeScript-strukturell kompatibilitetsregler, kan den tildeles et array - derfor er det ingen feil i koden din.
Dette er annerledes enn det du ville fått i JavaScript ved kjøretid. Ikke-enumerable egenskaper av arrayen ville ikke bli kopiert til et objekt, og resultatet ville bare ha to egenskaper som kommer fra array-indekser - "1" og "2".
Dette er en svakhet ved TypeScript sitt typesystem - det finnes ingen måte å ta hensyn til ikke-oppregnede egenskaper på, de behandles som om de var oppregnede som alle andre egenskaper. Hvis det fantes, ville denne tildelingen ha gitt en feil.
