typescript - Är det möjligt att initialisera ett objekt inuti en annan objektsinitialisering utan konstruktörer?
Det jag behöver är ganska enkelt, jag vill bara initiera ett objekt som är ett barn till ett annat objekt som jag håller på att initiera. I C# skulle det se ut ungefär så här:
var car = new Car {
serialNumber = 25,
engine = new Engine {
horsePower = 500
}
}
I detta exempel kod initierar jag Engine-typen inom initieringen av Car-typen. När jag försöker göra detta med TypeScript får jag syntaxfel oavsett vad jag försöker.
Här är min TypeScript-kod:
var car: Car = new Car({
serialNumber: 25,
engine: new Engine({
horsePower: 500
})
});
Det här kodblocket fungerar helt enkelt inte, och alla klasser som används i koden här är uppenbarligen importerade.
Kan det verkligen vara en grundläggande funktion som inte stöds i TypeScript?
REDIGERA: Det finns ingen konstruktor i dessa klasser. Så här ser de ut:
export class Car {
serialNumber: number;
engine: Engine;
}
Svar #1
Du kan absolut göra detta, du behöver bara skicka de korrekta konstruktörsargumenten.
Koden du har skrivit skickar ett enskilt konstruktörsargumentobjekt med nycklar. Så dina klasser bör se ut ungefär så här:
class Car {
constructor(args: { serialNumber: number; engine: Engine; }) { }
}
class Engine {
constructor(args: { horsePower: number; }) { }
}
Om dina klasser däremot använder flera namngivna konstruktörsargument, som detta:
class Car {
constructor(serialNumber: number, engine: Engine) { }
}
class Engine {
constructor(horsePower: number) { }
}
Då måste du helt enkelt skicka dina konstruktörsargument korrekt:
const car: Car = new Car(25, new Engine(500));
REDIGERA
det skulle kräva att jag skapar en konstruktor vilket är lite irriterande
Jag är lite förvirrad... din ursprungliga kod använder klasser, så du borde redan ha en konstruktor om du inte lägger till varje egenskap med en tilldelning. Vänligen posta ett komplett exempel.
Om du bara försöker skapa en nästlad objektlitteralstruktur, behöver du bara ett gränssnitt, och sedan skapa objektet med normal JS-objektlitteralnotation:
interface Car {
serialNumber: number;
engine: Engine;
}
interface Engine {
horsePower: number;
}
const car: Car = {
serialNumber: 25,
engine: {
horsePower: 500
}
};
Om du försöker tilldela ett objektliteral till en klastyp, då gör du fel. :)
REDIGERA 2
Så, du har en klass med egenskaper och ingen konstruktor. Det betyder att du inte kan instansiera den med egenskaper, varken inbäddade eller en åt gången. Du kan skriva en generell hjälpfunktion för att instansiera en klass och tilldela egenskaper:
function create<T>(constructor: new() => T, props: Partial<T>): T {
let instance = new constructor();
for (let key in props) {
instance[key] = props[key];
}
return instance;
}
Och sedan skapa ett objekt av en nästlad klass så här:
const car = create(Car, {
serialNumber: 123,
engine: create(Engine, {
horsePower: 456
})
});
Men om dina klasser verkligen bara har egenskaper, tror jag att du skulle ha det bättre med att bara använda gränssnitt och objektliteraler (som i mitt tidigare exempel).
Svar #2
Ditt svar är definitivt att du kan. Men din syntax har ett problem.
var car = new Car(
serialNumber: 25,
engine: new Engine{
horsePower: 500
}
);
och Car-klassen bör vara så här:
public class Car(int serialNumber, Engine engine) {
.....
}
