Varför tillåter TypeScript detta?
I TypeScript gör jag en GET-förfrågan som resulterar i ett JS-objekt som ser ut så här:
// Note: The variable is not actually declared and hardcoded like this
// This is just to demonstrate what the received object looks like
let obj = {id: "1"};
Och jag har även följande klass:
export class Test {
constructor(public id: number) { }
}
Jag skapar sedan en ny instans av denna klass på följande sätt:
let aClass = new Test(obj.id);
Och till min förvåning skapas instansen helt utan problem. Först tänkte jag "Cool! Den försöker automatiskt konvertera id till ett nummer!" men så är inte fallet, och det förvirrar mig lite.
console.log(typeof aClass.id);
Avslöjar att id är av typen sträng. Jag vägrade envist att tro det och försökte:
console.log(aClass.id += 12);
Och som jag borde ha förväntat mig vid det här laget, lade det till "12" till strängen.
Nu är min fråga: varför händer detta och varför kastar det inte ett fel istället?
Svar #1
Saken är den att Typescript-typning tillämpas vid kompilering.
De data du hämtar från din GET-förfrågan kommer alltid att behandlas som any om du inte gör något åt det. Eftersom Typescript inte har något sätt att avgöra vilken typ av data det är (kan vara vad som helst).
Det du kan göra är att starkt typa returvärdena från din GET-förfrågan. Då kommer TypeScript att ge dig ett fel. Men varning, det kommer inte att ge dig ett fel om GET-förfrågan inte returnerar de önskade uppgifterna.
const data: {
id: string,
} = GET();
// ...
För validering finns det några tillägg tillgängliga, som https://github.com/hapijs/joi
Jag rekommenderar att du definierar gränssnitt för varje GET-förfrågan, som:
interface GetUserR {
users: {
id: string,
name: string,
}[],
}
const users: GetUserR = await requester.GET('users');
På det här sättet får du autokomplettering, fel är lätta att upptäcka och det är utvecklingsbart. Det bästa vore att låta din backend generera dessa gränssnitt om du hanterar både fronten och backen.
