javascript - Typescript: Nesporazum oko duck typinga
Učim TypeScript čitajući priručnike i dokumentaciju. I samo me zanima kako TypeScript Duck Typing funkcionira.
Na primjer, ovaj kod daje Type error (koristeći službeni Typescript Playground)
interface Point {
x: number;
y: number;
}
const p: Point = {
x: 1,
y: 2,
z: 3
}
function printPoint(p: Point) {
console.log(p.x + p.y);
}
printPoint(p);
ali ovaj kod ne daje Type error
interface Point {
x: number;
y: number;
}
const p = {
x: 1,
y: 2,
z: 3
}
function printPoint(p: Point) {
console.log(p.x + p.y);
}
printPoint(p);
Mislim da je problem vezan uz Typescript-ovo Duck Typing, ali nisam mogao razumjeti zašto sustav tipova argumenata i sustav tipova konstante funkcioniraju na različit način.
jesam li pogrešno shvatio Duck Typing? const p sadrži x, y, pa mislim da bi const p: Point trebao raditi
Odgovor #1
Typescript nameće različite razine strogoće ovisno o tome što radite. Kada kreirate varijablu s eksplicitnim tipom, typescript je vrlo strog u vezi s tim što mora biti prisutno, ne dopuštajući dodatna svojstva. Dodatno svojstvo vjerojatno je greška u vašem kodu, budući da kreirate vrijednost a zatim odmah dodjeljujete tip, što tu vrijednost čini nedostupnom. Dakle, dodatna strogoća pomaže vam uhvatiti takve greške.
Kada pokušate dodijeliti jednu varijablu drugoj, uključujući prosljeđivanje varijable u funkciju, TypeScript provodi popustljiviju provjeru. Dvije varijable samo trebaju biti kompatibilne jedna s drugom, što otprilike znači da moraju imati barem navedena svojstva s ispravnim tipovima, ali je u redu ako imaju i dodatna svojstva. Ova popustljivija razina provjere dio je načina na koji TypeScript podržava podtipove i podklase. Trebali biste moći proslijediti podklasu tamo gdje se traži osnovna klasa (princip Liskovljeve supstitucije), ali podklasa će često imati dodatna svojstva.
Pogledajte ovaj link za više informacija o kompatibilnosti tipova: https://www.typescriptlang.org/docs/handbook/type-compatibility.html
Odgovor #2
Prvi kod je prikazao TypeError jer sučelje Point nema član z. Drugi kod nije imao pogrešku tipa, jer u funkciji sve svojstva na koja se referencira (x i y) postoje u tipu Point. To je zbog Duck Typinga i činjenice da se prihvaća kao Point ili ne, jer član z nije referenciran. Unutar funkcije, ako pokušate koristiti p.z, dobit ćete pogrešku tipa.