typescript - Objektet kan muligens være 'undefined'.ts(2532) med valgfrie argumenter
Jeg har denne koden:
export default class MyRandomClass {
private posFloat32Array?: Float32Array;
private otherArgument?: number;
constructor(params:MyRandomClass = {} as MyRandomClass) {
const {
posFloat32Array,
otherArgument,
} = params;
this.posFloat32Array = (posFloat32Array !== undefined) ? posFloat32Array : new Float32Array();
this.otherArgument = (otherArgument !== undefined) ? otherArgument : 0;
}
classMethod():void {
const total = this.posFloat32Array?.length + 3; //error
}
}
Det er ikke mulig at objektet er udefinert, men jeg får fortsatt feilen. Mitt mål er å ha en klasse som kan konstrueres med argumenter gitt på forskjellige måter, slik at utdataene alltid blir de samme. Dette etterligner konstruktøroverlasting som i dette eksempelet.
Jeg antar det burde være en mulig måte å ha en funksjon/klasse med valgfrie argumenter og deretter fortelle kompilatoren at argumentet faktisk har blitt sendt inn, eller hvis ikke, at det udefinerte scenarioet er håndtert deretter.
Hvordan kan dette håndteres med valgfrie argumenter?
REDIGER: Så langt jeg har undersøkt, ved å ta kodeeksempelet herfra, er det ikke mulig å gjøre klassevariablene dine valgfrie og få kompilatoren til å vite at de ikke vil være udefinerte og bruke dem i metodene dine, uten å lage en separat type for argumentene, gjøre denne typeargumentene valgfrie og klassevariablene ikke valgfrie, noe som er litt omstendelig hvis klassen er stor. Jeg vil gjerne bekrefte om dette er en gyldig eller den beste tilnærmingen for å håndtere valgfrie argumenter i TypeScript-klasser.
Svar #1
Du må skille grensesnittet ditt, siden klassen ikke lenger beskriver objektet med innkommende parametere. Svaret mitt viser en mer elegant måte å sette standardverdier på. Og siden du setter standardverdier, er parameterne i grensesnittet valgfrie, men de er garantert innenfor klassen (merk hvor spørsmålstegnene har flyttet seg). Dette bør fungere for deg:
interface MyNotSoRandomInterface {
posFloat32Array?: Float32Array;
otherArgument?: number;
}
export default class MyRandomClass {
private posFloat32Array: Float32Array;
private otherArgument: number;
constructor(params:MyNotSoRandomInterface = {} as MyNotSoRandomInterface) {
const {
posFloat32Array = new Float32Array(),
otherArgument = 0,
} = params;
this.posFloat32Array = posFloat32Array;
this.otherArgument = otherArgument;
}
classMethod():void {
const total = this.posFloat32Array.length + 3; //no errors!
}
}
Svar #2
Kompilatoren klager fordi du har definert den egenskapen som valgfri med ?. Problemet ligger i dine deklarasjoner.
Siden du har en konstruktør og posFloat32Array og otherArgument alltid settes i konstruktøren til eksplisitte verdier, trenger ikke disse egenskapene å markeres som valgfrie. Du bør fjerne markeringen av disse egenskapene som valgfrie.
Når skulle jeg ønske at klasseegenskaper var valgfrie da?
Dette er et flott spørsmål! Hvis du ikke eksplisitt implementerte en konstruktør, eller du ikke eksplisitt setter disse verdiene i konstruktøren, er dette når du kanskje vil merke en egenskap som valgfri. For eksempel kan klassen nedenfor instansieres uten at disse verdiene er definert eksplisitt. Det kan være et godt eksempel på når man bør merke dem som valgfri.
class MyRandomClass {
private posFloat32Array?: Float32Array;
private otherArgument?: number;
classMethod():void {
const total = this.posFloat32Array?.length ?? 0 + 3;
}
}
