NEWS
[Gelöst] TypeScript Kompilierfehler setObject
-
Ich versuche mit TypeScript die Methode setObject() aufzurufen, aber bekomme einen Compilierfehler.
const objId = 'shelly.0.SHPLG2-1#49FE33#1.online'; let obj = getObject(objId); if (!obj.common.custom) { obj.common.custom = {}; } obj.common.custom['statistics.0'] = { "enabled": true, "count": false, "sumCount": false, "timeCount": true, "fiveMin": false, "impUnitPerImpulse": 1, "impUnit": "", "avg": false, "minmax": false, "sumDelta": false, "sumIgnoreMinus": false, "groupFactor": 1, "logName": "online_script_trockner" }; setObject(objId, obj);
Hat jemand eine Idee was ich ändern kann oder was ich falsch mache?
javascript.1 (486) script.js.common.Berechnungen.Test_Statistics: TypeScript compilation failed: setObject(objId, obj); ^ ERROR: Argument of type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" \| "channel" \| "folder" \| "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to parameter of type '(Omit<StateObject, "acl" \| "_id"> & { _id?: string; acl?: StateACL; }) \| (Omit<InstanceObject, "acl" \| "_id"> & { _id?: string; acl?: ObjectACL; }) \| ... 10 more ... \| (Omit<...> & { ...; })'. Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" \| "channel" \| "folder" \| "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'Omit<OtherObject, "acl" \| "_id"> & { _id?: string; acl?: ObjectACL; }'. Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" \| "channel" \| "folder" \| "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'Omit<OtherObject, "acl" \| "_id">'. Types of property 'common' are incompatible. Property 'name' is missing in type '{ [x: string]: any; [x: number]: any; }' but required in type 'OtherCommon'.
-
@uwe72 sagte: mit TypeScript die Methode setObject() aufzurufen
Das sieht nach Javascript aus. Mit TypeScript kenne ich mich nicht aus.
-
@paul53 @AlCalzone nutzt IMHO TypeScript. Vielleicht kann der helfen
-
@uwe72 sagte in TypeScript Kompilierfehler setObject:
Property
ganz exakt kann ich es dir nicht sagen.
Typescript ist ja ein Aufsatz auf javascript um typensicherheit abbilden zu können.
daher musst du beim schreiben von objekten ein paar dinge berücksichtigen, damit die typen zusammenpassen.der fehler der mir am ehesten auffällt, steht ganz am Ende des Fehlertextes
Types of property 'common' are incompatible. Property 'name' is missing in type '{ [x: string]: any; [x: number]: any; }' but required in type 'OtherCommon'.
es sieht so aus, als ob du in common das namens-attribut vergessen hast, den iobroker auf jeden fall haben will.
genaueres, sollte man hier heraus lesen können
https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/objectsschema.mddie lange liste am anfang des fehlertextes listet nur die verschiedenen typ-möglichkeiten auf, gegen die typescript geprüft hat. durch typ-überladung kann ein objekt auch verschiedene arten von Abbildungen annehmen.
-
@oliverio Danke dir.
Für mich ist dies allerdings auch ein Bug im TypeScript "Adapter", den dieser (sinnfreie) Code hier sollte eigentlich schon funktionieren?!
const objId = 'shelly.0.SHPLG2-1#49FE33#1.online'; let obj = getObject(objId); setObject(objId, obj);
Bringt aber den gleichen Fehler. Eigentlich hole ich mir ja die Struktur und möchte diese nur anreichern. Von dem her sollte das .name Property ja gefüllt bzw. vorhanden sein?!
```javascript.1 (486) script.js.common.Berechnungen.Test_Statistics: TypeScript compilation failed: setObject(objId, obj); ^ ERROR: Argument of type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" | "channel" | "folder" | "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to parameter of type '(Omit<StateObject, "acl" | "_id"> & { _id?: string; acl?: StateACL; }) | (Omit<InstanceObject, "acl" | "_id"> & { _id?: string; acl?: ObjectACL; }) | ... 10 more ... | (Omit<...> & { ...; })'. Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" | "channel" | "folder" | "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'Omit<OtherObject, "acl" | "_id"> & { _id?: string; acl?: ObjectACL; }'. Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" | "channel" | "folder" | "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'Omit<OtherObject, "acl" | "_id">'. Types of property 'common' are incompatible. Property 'name' is missing in type '{ [x: string]: any; [x: number]: any; }' but required in type 'OtherCommon'.
-
So scheint es zu funktionieren:
const originalDatenpunkt = 'shelly.0.SHPLG2-1#49FE33#1.online'; setObject(originalDatenpunkt, { type: 'state', common: { name: getObject(originalDatenpunkt).common.name, type: getObject(originalDatenpunkt).common.type, unit: getObject(originalDatenpunkt).common.unit, read: true, write: true, role: getObject(originalDatenpunkt).common.role, alias: { id: originalDatenpunkt }, custom: { "statistics.0": { "enabled": true, "count": false, "fiveMin": false, "sumCount": false, "impUnitPerImpulse": 1, "impUnit": "", "timeCount": true, "avg": false, "minmax": false, "sumDelta": false, "sumIgnoreMinus": false, "groupFactor": 1, "logName": "online2" } } }, native: {} });
-
@uwe72 sagte in TypeScript Kompilierfehler setObject:
So scheint es zu funktionieren:
Damit wäre ich aber vorsichtig, da Du die Objekte änderst (z.B. read und write) und auch andere custom settings verwirfst. Bitte produktiv nicht so verwenden.
-
Gebe ich dir recht, insbesondere bei read/write. Dies könnte ich noch analog den anderen Einstellungen ändern.
Bei custom hatte ich auch die Sorge, dass wenn da schon andere Custom-Einstellungen existieren für andere Adapter, z.B. Telegram, dass dies dann überschrieben wird und somit entfernt wird. Der Test hatte aber funktioniert.
So oder so, wäre es nur ein hässlicher Workarround, der ja, ggf. auch Schaden anrichtet.
Hast Du mir ein Verbesserungsvorschlag für meinen initialen Versuch? Danke dir.
Vermutlich aber gar nicht so einfach, siehe #5
https://forum.iobroker.net/topic/57264/typescript-kompilierfehler-setobject/5
Für mich sieht dies nach einem Bug im TypeScript "Adapter" aus. -
@uwe72 Rein beim Drüberschauen würde ich vermuten, dass anhand der Objekt-ID nicht 100% klar ist, was das genau für ein Objekt ist. Wenn du TS auf die Sprünge hilfst, z.B.(
let obj: iobJS.StateObject = getObject(objId);
für einen State, oder
let obj: iobJS.ChannelObject = getObject(objId);
für einen Channel, etc., dann sollte die Zuweisung auch klappen (hoffentlich). Sonst muss ich nochmal schauen, ob das etwas weniger "auf die Fresse" geht
-
@alcalzone said in TypeScript Kompilierfehler setObject:
let obj: iobJS.StateObject = getObject(objId);
Ich habe es nun so:
const originalDatenpunkt = 'shelly.0.SHPLG2-1#49FE33#1.online'; let obj: iobJS.StateObject = getObject(originalDatenpunkt);
Bekomme diesen Fehler:
javascript.1 (486) script.js.common.Berechnungen.Test_Statistics: TypeScript compilation failed: let obj: iobJS.StateObject = getObject(originalDatenpunkt); ^ ERROR: Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" | "channel" | "folder" | "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'StateObject'. Types of property 'type' are incompatible. Type '"state" | "channel" | "folder" | "device"' is not assignable to type '"state"'. Type '"channel"' is not assignable to type '"state"'.
D.h. "obj" wird schon im Editor angemeckert:
-
@uwe72
Und was steht im iobroker was für ein Typ das Objekt ist? -
Da steht das gleiche wie oben als Text gepostet:
javascript.1 (486) script.js.common.Berechnungen.Test_Statistics: TypeScript compilation failed: let obj: iobJS.StateObject = getObject(originalDatenpunkt); ^ ERROR: Type '{ common: { [x: string]: any; [x: number]: any; }; type: "state" | "channel" | "folder" | "device"; acl: { object: number; state: number; owner: string; ownerGroup: string; }; _id: string; native: { [x: string]: any; }; enums: { ...; }; from: string; user: string; ts: number; }' is not assignable to type 'StateObject'. Types of property 'type' are incompatible. Type '"state" | "channel" | "folder" | "device"' is not assignable to type '"state"'. Type '"channel"' is not assignable to type '"state"'.
-
@uwe72
ich denke das in der Ansicht des Objektbaums bei Typ
channel dran steht.
Auf Typ channel kannst du kein typ state setzen., da channel kein attribut common.custom besitzt
oder es ist umgekehrt, das kann ich nicht so richtig rauslesen@uwe72 sagte in TypeScript Kompilierfehler setObject:
Type '"channel"' is not assignable to type '"state"'.
warum willst du unbedingt in custom was reinschreiben? ganz davon abgesehen, das es schon gehen muss, aber wenn du eine objektstruktur in einem datenpunkt ablegen willst, dann würde ich einfach mit
getState und setState arbeiten und das Objekt dort einfach mit JSON.stringify und JSON.parse schreiben und lesen.und was mir noch aufgefallen ist:
statistics.0 ist kein eigener datenpunkt
das erste richtige objekt in der hierarchie ist
statistics.0.save und
statistics.0.tempstatistics.0 sieht zwar so aus, existiert für sich aber nicht als eigenständiges objekt
dies ist erkennbar, das im objektbaum bei typ nix dran steht. -
@oliverio Ich möchte ja programmatisch für einen Datenpunkt den Statistic-Adapter aktivieren.
Habe ein Array mit allen Devices (ca. 200-250). So kann ich generisch wie gesagt für alle Devices den StatisticAdapter aktivieren.
-
@alcalzone Siehe zuvor. Hättest Du mir noch einen Tipp? Grüße aus Brasilien. Uwe
-
@oliverio sagte in TypeScript Kompilierfehler setObject:
statistics.0 sieht zwar so aus, existiert für sich aber nicht als eigenständiges objekt
dies ist erkennbar, das im objektbaum bei typ nix dran steht.Das ist normal und auch richtig so. Bei einigen Adaptern wird das als Objekt für den File-Meta-Storage angelegt (z.B. vis). Aber das ist ganz selten und hat mit dem Problem nichts zu tun.
-
@uwe72 Ok dann anders:
const originalDatenpunkt = 'shelly.0.SHPLG2-1#49FE33#1.online'; let obj = getObject(originalDatenpunkt) as iobJS.StateObject;
Der Unterschied zur vorherigen Variante ist dass du TS jetzt sagst: "Ich bin mir sicher, das ist ein StateObject". Das andere hat bedeutet: "obj ist ein State, lese mir da das Objekt xyz rein" (was nicht garantiert ein StateObject ist)
-
@alcalzone Perfekt, danke dir! Bin wirklich sehr dankbar nun eine funktionierende programmatische Lösung zu haben (für das "Aktivieren" vom Statistikadapter, o.ä.) Hat nun funktioniert:
const objId = 'shelly.0.SHPLG2-1#49FE33#1.online'; let obj = getObject(objId) as iobJS.StateObject; if (!obj.common.custom) { obj.common.custom = {}; } obj.common.custom['statistics.0'] = { "enabled": true, "count": false, "sumCount": false, "timeCount": true, "fiveMin": false, "impUnitPerImpulse": 1, "impUnit": "", "avg": false, "minmax": false, "sumDelta": false, "sumIgnoreMinus": false, "groupFactor": 1, "logName": "online_script_trockner" }; setObject(objId, obj);
-
Bitte diesen Kommentar löschen, habe ein neues Ticket aufgemacht:
https://forum.iobroker.net/topic/57367/typescript-zugriff-iobjs-stateobject-innerhalb-foreach