NEWS
Typescript: Problem mit getObject()
-
Hallo,
eines meiner (typescript) Scripte läuft nicht mehr weil es da einen Tranpilationsfehler gibt. Das Script ist aber schon gelaufen, nur gibt es neuerdings diesen Fehler. Ich nehme an, dass das mit dem Update des Javascript-Adapters zu tun hat?.Die Fehlerzeile:
let deviceName:string = getObject(deviceId).common.name;Das Objekt sieht folgendermassen aus:
{ type: 'channel', common: { name: 'Taster_Markise' }, _id: 'alias.0.Taster_Markise', native: {}, from: 'system.adapter.admin.0', user: 'system.user.admin', ts: 1752846792596, acl: { object: 1636, owner: 'system.user.admin', ownerGroup: 'system.group.administrator' } }Fehlermeldung:
TypeScript compilation failed: deviceName = getObject(deviceId).common.name; ^ ERROR: Type 'StringOrTranslated' is not assignable to type 'string'. Type 'Translated' is not assignable to type 'string'.Frage ich zuerst das Objekt und dann ".common" ab, sagt der transpiler, dass common nicht existiere. Klar, typescript kennt diesen typ offenbar nicht (mehr?).
Aber das Script lief schon.
Die beschreibung in der Doku sagt mir leider auch nicht viel mehr. -
Vorab: Ich kenn mich mit typescript im javascritp Adapzter nicht aus aber
Im State Object des cores kann common.name entweder ein einfacher String oder ein i18n Objekt ('{en:'english text', de:'deuter Text', ...} sein. Insofern erscheint es richtig dass TS meckert da da nicht zwingen ein String retourniert wird wenn du auf common.name zugreifst.
Aber wie gesagt es kann sein, dass der javascritp Adapter da auch Datenstrukturen automatisch migriert (und z.b. nicht das originale state Object retourniert)
Eventuell hat dein Skript bei einem ANDEREN Objekt funtkioniert wo wirklich nur ein String drinnen stand?
-
Vorab: Ich kenn mich mit typescript im javascritp Adapzter nicht aus aber
Im State Object des cores kann common.name entweder ein einfacher String oder ein i18n Objekt ('{en:'english text', de:'deuter Text', ...} sein. Insofern erscheint es richtig dass TS meckert da da nicht zwingen ein String retourniert wird wenn du auf common.name zugreifst.
Aber wie gesagt es kann sein, dass der javascritp Adapter da auch Datenstrukturen automatisch migriert (und z.b. nicht das originale state Object retourniert)
Eventuell hat dein Skript bei einem ANDEREN Objekt funtkioniert wo wirklich nur ein String drinnen stand?
@mcm1957 sagte in Typescript: Problem mit getObject():
Im State Object des cores kann common.name entweder ein einfacher String oder ein i18n Objekt ('{en:'english text', de:'deuter Text', ...} sein. Insofern erscheint es richtig dass TS meckert da da nicht zwingen ein String retourniert wird wenn du auf common.name zugreifst.
Ich weiss nicht ob das ein State Object des cores ist (normaler Datenpunkt, dem ich den Namen 'Taster_Markise' gegeben hab).
Aber er kennt nicht mal 'common', denn das wollte ich abfragen:let obj = console.log(getObject(deviceId)); let s:string = obj.common;fehler:
TypeScript compilation failed: let s: string = obj.common; ^ ERROR: Property 'common' does not exist on type 'void'.@mcm1957 sagte in Typescript: Problem mit getObject():
Eventuell hat dein Skript bei einem ANDEREN Objekt funtkioniert wo wirklich nur ein String drinnen stand?
Nein, das script lief bis vor kurzem und den Fehler hab ich nun, weil ich herausfand dass das script nicht mehr läuft. Wahrscheinlich nun nach dem update (3 Tage).
-
Ja und die types werden immer genau - also das was mcm geschrieben hat.
common.name kann ein string sein oder ein object - daher prüfen ob es ein string ist. -
@mcm1957 sagte in Typescript: Problem mit getObject():
Im State Object des cores kann common.name entweder ein einfacher String oder ein i18n Objekt ('{en:'english text', de:'deuter Text', ...} sein. Insofern erscheint es richtig dass TS meckert da da nicht zwingen ein String retourniert wird wenn du auf common.name zugreifst.
Ich weiss nicht ob das ein State Object des cores ist (normaler Datenpunkt, dem ich den Namen 'Taster_Markise' gegeben hab).
Aber er kennt nicht mal 'common', denn das wollte ich abfragen:let obj = console.log(getObject(deviceId)); let s:string = obj.common;fehler:
TypeScript compilation failed: let s: string = obj.common; ^ ERROR: Property 'common' does not exist on type 'void'.@mcm1957 sagte in Typescript: Problem mit getObject():
Eventuell hat dein Skript bei einem ANDEREN Objekt funtkioniert wo wirklich nur ein String drinnen stand?
Nein, das script lief bis vor kurzem und den Fehler hab ich nun, weil ich herausfand dass das script nicht mehr läuft. Wahrscheinlich nun nach dem update (3 Tage).
-
@iob69 sagte in Typescript: Problem mit getObject():
let obj = console.log(getObject(deviceId));
let s:string = obj.common;schau nochmal was da steht
console.log retourniert doch kein objectund obj.common ist niemals ein string
@mcm1957 sagte in Typescript: Problem mit getObject():
schau nochmal was da steht
Ja, das ist natürlich quatsch, da hab ich beim debuggen was falsch zusammenkopiert. Ich hab's jetzt so versucht:
let obj = getObject(deviceId); // ergibt ein objekt let s = obj.common; // ergibt ein objekt let s2 = s.name; console.log(typeof(s2)); // ergibt ein stringaber
deviceName=getObject(deviceId).common.name;gibt offenbar neu diesen compiler-Fehler:
TypeScript compilation failed: deviceName = getObject(deviceId).common.name; ^ ERROR: Type 'StringOrTranslated' is not assignable to type 'string'. Type 'Translated' is not assignable to type 'string'. -
Wenn deviceName vom Typ string ist, dann ist die Fehlermeldung korrekt.
getObject liefert wie schon geschrieben den Typ StringOrTranslated, das ist konkret entweder ein String oder ein Objekt zurück. Der Typ ist eben KEIN einfacher String und kann einem String nicht zugewiesen werden. Da der Kompiler nicht weiß ob beim abgefragten State nun eine String oder ein Objekt retoruniert wird, meldet er zurecht einen Fehler wenn du versuchst es in einem String zu speichern.
Verwende die richtigen Typen oder frage ab ob ein String zurückkommt oder ein Objekt. Das musst du eh tun wenn du den Namenseintrag richtig verarbeiten willst.
-
ok, ich hab's jetzt so gelöst. Da ich sicher weiss, dass 'name' das ein string ist und sich dieser nicht ändert, kann ich ihn gleich casten.
let name:string = getObject(deviceId).common.name as string;
Ich begreif zwar das problem, dass der Compiler nicht in die Struktur sehen kann, aber ich kapier immer noch nicht wieso das plötzlich als Problem aufgetaucht ist, wo es schon seit zwei Jahren so lief.PS: kann man solche Strukturen nicht irgendwie abfragen, rsp. dem Compiler mitteilen, so dass dieser die Datenstruktur kennt?
Dazu müsste man aber die Konkrete Klasse kennen, die so ein Objekt (in diesem Fall ein Datenpunkt, der aber je nachdem wie er erzeugt wird ja andere Typen hat) darstellt. -
Ich hab das doch oben erklärt - types sind da um dir zu helfen und wenn das mit
common: { name: any; //... }definiert ist wäre eine Verbesserung das als:
common: { name: StringOrTranslated; //... }zu definieren.
Anstatt es zu casten kannste es auch richtig machen:
const cname = getObject(deviceId).common.name; let name: string = typeof cname === 'string' ? cname : cname?.de ? cname.de : cname.enweiß nicht genau was der scriptadapter da zurück liefert, daher wäre für mich die richtig lösung
const obj = getObject(deviceId) const cname = obj?.common?.name let name: string = typeof cname === 'string' ? cname : cname?.de ? cname.de : (cname?.en ?? '')