mongodb - Konverter mongoose JavaScript-kode til TypeScript. Denne referansen gikk tapt
Jeg startet dette nye eventyret med å lære Typescript. Jeg tok et Node.js-prosjekt skrevet selvfølgelig i JavaScript, og jeg konverterer det til Typescript. Ideen min er å se alle fordelene og å lære hvor problemene er, hvilke mønstre jeg bør bruke og så videre.
Prosjektet bruker MongoDB-database med Mongoose JavaScript-bibliotek, og jeg sliter med hvordan Typescript transpilerer koden. Enkelt sagt: jeg mister this-referansen.
Her er et godt eksempel som vil forårsake problemet.
var personSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
updated:{
type: Date,
},
});
personSchema.pre('save', function(next) {
// Make sure updated holds the current date/time
this.updated = new Date();
next();
});
var Person = mongoose.model('Person', personSchema);
I pre-save-funksjonen er det en this-referanse. Dette er en referanse til den nåværende personen med den oppdaterte egenskapen. Alt er i orden. Jeg har sett dette mønsteret i forskjellige eksempler.
Dette er første gang jeg jobber med et Node.js-prosjekt.
Her er hvordan jeg prøvde en enkel TypeScript-konvertering:
interface IPerson extends mongoose.Document{
created:Date;
updated:Date;
}
var personSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
updated: {
type: Date
}
});
personSchema.pre('save', (next) => {
// Make sure updated holds the current date/time
this.updated = new Date();
next();
});
export = mongoose.model<IPerson>('Person', personSchema);
Etter at TypeScript-transpilerne har transpillert koden, blir 'this' byttet med _this. Øverst i filen ser du var _this=this;. Dette er galt. Den nye JavaScript-filen mister referansen til person-objektet.
Kan noen hjelpe meg med hvordan man korrekt kan konvertere JavaScript til TypeScript? Hvordan bør jeg løse denne typen problemer? Finnes det et mønster?
Mitt første inntrykk er at det noen ganger ikke er rett frem å konvertere JavaScript til TypeScript, men jeg liker det veldig godt.
Svar #1
Prøv dette:
var personSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
updated: {
type: Date
}
saveHandler(next) {
// Make sure updated holds the current date/time
this.updated = new Date();
next();
}
});
personSchema.pre('save', personSchema.saveHandler);
Svar #2
Så dette spørsmålet er litt gammelt, og jeg er ikke sikker på om du allerede har løst det, men det finnes ikke noe valgt svar på det, så dette kan kanskje hjelpe noen andre der ute.
Jeg slet med dette selv en stund, og jeg tror jeg har funnet ut av det.
Ta også i betraktning at hver kode er forskjellig, så dette løser kanskje ikke problemet i alle tilfeller, men prøv å kvitte deg med pilfunksjonen. Bruk en vanlig funksjon i stedet.
ES6s pilfunksjoner bruker leksikalsk scoping, så "this" er ikke det du faktisk forventer i dette tilfellet. Det er mest sannsynlig, vel... undefined, eller selve skjemaet. Det peker ikke på dokumentet, derfor vil det ikke finne noen av dets metoder og/eller egenskaper.
