typescript - Hvordan er det mulig å «duck type» et objekt når klassen har innkapslede egenskaper?
Jeg lurte på om det er en god praksis å bruke accessors i TS, og da jeg testet tilfeller la jeg merke til at det å gjøre det, gjør at du mister «funksjonen» med «duck-typing».
Er det designet for å forhindre at utviklere gjør uønskede skrivefeil, eller går jeg glipp av noe?
class BlogPost {
constructor(private _title: string, private _summary: string,
private _hoverTitle?: string) {
}
public get title(): string {
return this._title;
}
public set title(value: string) {
this._title = value;
}
public get summary(): string {
return this._summary;
}
public set summary(value: string) {
this._summary = value;
}
public get hoverTitle(): string {
return this._hoverTitle;
}
public set hoverTitle(value: string) {
this._hoverTitle = value;
}
}
let blogPostItem: BlogPost;
blogPostItem = {
hoverTitle = '',
summary = '',
title = ''
}
Dette bør være en gyldig tildeling, men det viser meg følgende feil:
Egenskapen 'hoverTitle' mangler i typen '{ title: string; _title: string; summary: string; _summary: any; }', men kreves i typen 'BlogPost'.
Når jeg prøver å legge til disse egenskapene, siden de er private, vises denne feilen:
Type '{ _hoverTitle: any; _summary: any; _title: any; hoverTitle: any; summary: any; title: any; }' kan ikke tildeles typen 'BlogPost'. Egenskapen '_title' er privat i typen 'BlogPost' men ikke i typen '{ _hoverTitle: any; _summary: any; _title: any; hoverTitle: any; summary: any; title: any; }'.
Er dette ment eller går jeg glipp av noe?
Her er en direktesendt forhåndsvisning av feilen
Jeg tror dette er en god måte å håndtere problemet på! forhåndsvisning
Bare la klassen implementere et grensesnitt og bruk deretter grensesnittet for «duck typing»... på denne måten spiller det ingen rolle om klassen har kapslede private felt fordi du typiserer som grensesnittet.
Dette kom fra @Titian Cernicova-Dragomirs svar...
Svar #1
Private felter får klassen til å oppføre seg normalt, det er ikke mulig å gi et alias til en klasse med private felter. Vi kan derimot fjerne dem ved å bruke Pick for å få kun de offentlige egenskapene:
let blogPostItem: Pick<BlogPost, keyof BlogPost>;
blogPostItem = {
hoverTitle: '',
summary: '',
title: ''
}
Du kan også bruke en typepåstand for å ignorere feilene.
Svar #2
For å endre på svaret til @Titian Cernicova-Dragomir,
Menige får klassen til å oppføre seg på en normal måte.
Merk at han sier «oppføre seg nominelt», men ikke «nominell».
Typen av klasse i TypeScript inkluderer private felt og sammenligner dem strukturelt. Det er et designvalg gjort av TS-teamet for å unngå utilsiktet tilgang eller overskriving av de private feltene.
Det skaper mye forvirring og smertepunkter, og en av hoveddrivkreftene for meg selv til å gjøre klassefri programmering i TS.
Pick<> er et fint triks for å komme rundt denne «begrensningen».
