Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. TypeScript und common.states (Record<string, string>)

NEWS

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    23
    1
    1.3k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.3k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    14
    1
    2.5k

TypeScript und common.states (Record<string, string>)

Geplant Angeheftet Gesperrt Verschoben JavaScript
7 Beiträge 3 Kommentatoren 778 Aufrufe 2 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • N Offline
    N Offline
    noox
    schrieb am zuletzt editiert von noox
    #1

    Ich habe gesehen, dass common.states (für createState) als Record<string, string> definiert ist: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/iobroker/index.d.ts

    So ganz happy bin ich mit dem Record nicht, weil man zumindest im einfachsten Fall mit Zeichenketten herum hantiert, wo natürlich schnell mal ein Tippfehler passieren kann. Außerdem hat man keine Autovervollständigung, wenn man mit der Variable weiterarbeitet.

    const stateValues1: Record<string, string> = {
        stateA:  'State A',
        stateB:  'State B',
    }
    var stateId1 = 'javascript.0.state1';
    createState(stateId1, 'stateA', false, {
        name: 'Status 1',
        type: 'string',
        read: true,
        write: false,
        unit: '',
        role: 'state',
        states: stateValues1
    });  
    var value1 = getState(stateId1).val;
    log(value1.toString());
    var someVar1 = 'stateB';
    if(value1 == someVar1) {}
    var someVar1b = 'sateB'; // Typo
    if(value1 == someVar1b) {}
    setState(stateId1, value1)
    
    

    Man könnte auch mit Konstanten arbeiten, aber Autovervollständigung hat man dann bei den States nicht:

    const state3A = 'stateA';
    const state3B = 'stateB';
    type State3 = 'stateA' | 'stateB';
    
    const stateValues3: Record<State3, string> = {
        [state3A]:  'State A',
        [state3B]:  'State B',
    }
    var stateId3 = 'javascript.0.state3';
    createState(stateId3, state3A, false, {
        name: 'Status 3',
        type: 'string',
        read: true,
        write: false,
        unit: '',
        role: 'state',
        states: stateValues3
    }); 
    var value3: State3  = getState(stateId3).val;
    log(value3.toString());
    var someVar3: State3 = state3B;
    //var someVar3b: State3 = 'sateA'; <-- typo not allowed
    if(value3 == someVar3) {}
    setState(stateId3, value3);
    

    Am besten würden mir folgende Variante mit Enums gefallen. Allerdings ist hier der State mit numerischen Keys definiert (common.type: 'number'). common.states daher als Record<number, string> statt Record<string, string>

    enum States2 {
        stateA,
        stateB
    }
    const stateValues2: Record<States2, string> = {
        [States2.stateA]:  'State A',
        [States2.stateB]:  'State B'
    }
    var stateId2 = 'javascript.0.state2';
    createState(stateId2, States2.stateA, false, {
        name: 'Status 2',
        type: 'number',
        read: true,
        write: false,
        unit: '',
        role: 'state',
        states: stateValues2
    }); 
    var value2: States2  = getState(stateId2).val;
    log(value2.toString());
    var someVar2 = States2.stateB;
    if(value2 == someVar2) {}
    setState(stateId2, value2);
    

    Es ginge zwar mit Enums auch mit Record<string, string> - das wird aber kompliziert:

    enum States4 {
        stateA,
        stateB,
    }    
    
    const stateValues4: Record<string, string> = {
        [States4[States4.stateA]]:  'State A',
        [States4[States4.stateB]]:  'State B'
    }
    var stateId4 = 'javascript.0.state4';
    createState(stateId4, States4[States4.stateA], false, {
        name: 'Status 4',
        type: 'string',
        read: true,
        write: false,
        unit: '',
        role: 'state',
        states: stateValues4
    });  
    var value4: States4 = States4[getState(stateId4).val as string];
    log(value4.toString());
    var someVar4: States4 = States4.stateB;
    if(value4 == someVar4) {}
    setState(stateId4, States4[value4]);
    

    Ich bin keine Typescript-Profi - vielleicht gibt's noch bessere Varianten. Ich finde es halt am schönsten, wenn man so States im Code als Enums definiert, weil man dann keine Tippfehler machen kann und Autovervollständigen hat.
    Ist es ein Problem, wenn der common.state als Record<number, string> und der State als "number" definiert ist?

    paul53P AlCalzoneA 2 Antworten Letzte Antwort
    0
    • N noox

      Ich habe gesehen, dass common.states (für createState) als Record<string, string> definiert ist: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/iobroker/index.d.ts

      So ganz happy bin ich mit dem Record nicht, weil man zumindest im einfachsten Fall mit Zeichenketten herum hantiert, wo natürlich schnell mal ein Tippfehler passieren kann. Außerdem hat man keine Autovervollständigung, wenn man mit der Variable weiterarbeitet.

      const stateValues1: Record<string, string> = {
          stateA:  'State A',
          stateB:  'State B',
      }
      var stateId1 = 'javascript.0.state1';
      createState(stateId1, 'stateA', false, {
          name: 'Status 1',
          type: 'string',
          read: true,
          write: false,
          unit: '',
          role: 'state',
          states: stateValues1
      });  
      var value1 = getState(stateId1).val;
      log(value1.toString());
      var someVar1 = 'stateB';
      if(value1 == someVar1) {}
      var someVar1b = 'sateB'; // Typo
      if(value1 == someVar1b) {}
      setState(stateId1, value1)
      
      

      Man könnte auch mit Konstanten arbeiten, aber Autovervollständigung hat man dann bei den States nicht:

      const state3A = 'stateA';
      const state3B = 'stateB';
      type State3 = 'stateA' | 'stateB';
      
      const stateValues3: Record<State3, string> = {
          [state3A]:  'State A',
          [state3B]:  'State B',
      }
      var stateId3 = 'javascript.0.state3';
      createState(stateId3, state3A, false, {
          name: 'Status 3',
          type: 'string',
          read: true,
          write: false,
          unit: '',
          role: 'state',
          states: stateValues3
      }); 
      var value3: State3  = getState(stateId3).val;
      log(value3.toString());
      var someVar3: State3 = state3B;
      //var someVar3b: State3 = 'sateA'; <-- typo not allowed
      if(value3 == someVar3) {}
      setState(stateId3, value3);
      

      Am besten würden mir folgende Variante mit Enums gefallen. Allerdings ist hier der State mit numerischen Keys definiert (common.type: 'number'). common.states daher als Record<number, string> statt Record<string, string>

      enum States2 {
          stateA,
          stateB
      }
      const stateValues2: Record<States2, string> = {
          [States2.stateA]:  'State A',
          [States2.stateB]:  'State B'
      }
      var stateId2 = 'javascript.0.state2';
      createState(stateId2, States2.stateA, false, {
          name: 'Status 2',
          type: 'number',
          read: true,
          write: false,
          unit: '',
          role: 'state',
          states: stateValues2
      }); 
      var value2: States2  = getState(stateId2).val;
      log(value2.toString());
      var someVar2 = States2.stateB;
      if(value2 == someVar2) {}
      setState(stateId2, value2);
      

      Es ginge zwar mit Enums auch mit Record<string, string> - das wird aber kompliziert:

      enum States4 {
          stateA,
          stateB,
      }    
      
      const stateValues4: Record<string, string> = {
          [States4[States4.stateA]]:  'State A',
          [States4[States4.stateB]]:  'State B'
      }
      var stateId4 = 'javascript.0.state4';
      createState(stateId4, States4[States4.stateA], false, {
          name: 'Status 4',
          type: 'string',
          read: true,
          write: false,
          unit: '',
          role: 'state',
          states: stateValues4
      });  
      var value4: States4 = States4[getState(stateId4).val as string];
      log(value4.toString());
      var someVar4: States4 = States4.stateB;
      if(value4 == someVar4) {}
      setState(stateId4, States4[value4]);
      

      Ich bin keine Typescript-Profi - vielleicht gibt's noch bessere Varianten. Ich finde es halt am schönsten, wenn man so States im Code als Enums definiert, weil man dann keine Tippfehler machen kann und Autovervollständigen hat.
      Ist es ein Problem, wenn der common.state als Record<number, string> und der State als "number" definiert ist?

      paul53P Offline
      paul53P Offline
      paul53
      schrieb am zuletzt editiert von
      #2

      @noox
      common.states ist als Objekt mit einer Anzahl diskreter Werte (false/true oder 0/1/2/...) denen Zustandstexte zugewiesen werden, definiert. Was soll daran geändert werden ?

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      N 1 Antwort Letzte Antwort
      0
      • N noox

        Ich habe gesehen, dass common.states (für createState) als Record<string, string> definiert ist: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/iobroker/index.d.ts

        So ganz happy bin ich mit dem Record nicht, weil man zumindest im einfachsten Fall mit Zeichenketten herum hantiert, wo natürlich schnell mal ein Tippfehler passieren kann. Außerdem hat man keine Autovervollständigung, wenn man mit der Variable weiterarbeitet.

        const stateValues1: Record<string, string> = {
            stateA:  'State A',
            stateB:  'State B',
        }
        var stateId1 = 'javascript.0.state1';
        createState(stateId1, 'stateA', false, {
            name: 'Status 1',
            type: 'string',
            read: true,
            write: false,
            unit: '',
            role: 'state',
            states: stateValues1
        });  
        var value1 = getState(stateId1).val;
        log(value1.toString());
        var someVar1 = 'stateB';
        if(value1 == someVar1) {}
        var someVar1b = 'sateB'; // Typo
        if(value1 == someVar1b) {}
        setState(stateId1, value1)
        
        

        Man könnte auch mit Konstanten arbeiten, aber Autovervollständigung hat man dann bei den States nicht:

        const state3A = 'stateA';
        const state3B = 'stateB';
        type State3 = 'stateA' | 'stateB';
        
        const stateValues3: Record<State3, string> = {
            [state3A]:  'State A',
            [state3B]:  'State B',
        }
        var stateId3 = 'javascript.0.state3';
        createState(stateId3, state3A, false, {
            name: 'Status 3',
            type: 'string',
            read: true,
            write: false,
            unit: '',
            role: 'state',
            states: stateValues3
        }); 
        var value3: State3  = getState(stateId3).val;
        log(value3.toString());
        var someVar3: State3 = state3B;
        //var someVar3b: State3 = 'sateA'; <-- typo not allowed
        if(value3 == someVar3) {}
        setState(stateId3, value3);
        

        Am besten würden mir folgende Variante mit Enums gefallen. Allerdings ist hier der State mit numerischen Keys definiert (common.type: 'number'). common.states daher als Record<number, string> statt Record<string, string>

        enum States2 {
            stateA,
            stateB
        }
        const stateValues2: Record<States2, string> = {
            [States2.stateA]:  'State A',
            [States2.stateB]:  'State B'
        }
        var stateId2 = 'javascript.0.state2';
        createState(stateId2, States2.stateA, false, {
            name: 'Status 2',
            type: 'number',
            read: true,
            write: false,
            unit: '',
            role: 'state',
            states: stateValues2
        }); 
        var value2: States2  = getState(stateId2).val;
        log(value2.toString());
        var someVar2 = States2.stateB;
        if(value2 == someVar2) {}
        setState(stateId2, value2);
        

        Es ginge zwar mit Enums auch mit Record<string, string> - das wird aber kompliziert:

        enum States4 {
            stateA,
            stateB,
        }    
        
        const stateValues4: Record<string, string> = {
            [States4[States4.stateA]]:  'State A',
            [States4[States4.stateB]]:  'State B'
        }
        var stateId4 = 'javascript.0.state4';
        createState(stateId4, States4[States4.stateA], false, {
            name: 'Status 4',
            type: 'string',
            read: true,
            write: false,
            unit: '',
            role: 'state',
            states: stateValues4
        });  
        var value4: States4 = States4[getState(stateId4).val as string];
        log(value4.toString());
        var someVar4: States4 = States4.stateB;
        if(value4 == someVar4) {}
        setState(stateId4, States4[value4]);
        

        Ich bin keine Typescript-Profi - vielleicht gibt's noch bessere Varianten. Ich finde es halt am schönsten, wenn man so States im Code als Enums definiert, weil man dann keine Tippfehler machen kann und Autovervollständigen hat.
        Ist es ein Problem, wenn der common.state als Record<number, string> und der State als "number" definiert ist?

        AlCalzoneA Offline
        AlCalzoneA Offline
        AlCalzone
        Developer
        schrieb am zuletzt editiert von
        #3

        @noox sagte in TypeScript und common.states (Record<string, string>):

        So ganz happy bin ich mit dem Record nicht, weil man zumindest im einfachsten Fall mit Zeichenketten herum hantiert, wo natürlich schnell mal ein Tippfehler passieren kann.

        Tippfehler abfangen in Objekten, die an Funktionen übergeben werden (wie der common-Teil an sich), funktioniert nur, wenn die Form des Objekts vorher bekannt ist. Im Falle von common.states ist das nicht gegeben, da hier jeder erdenklicher Key erlaubt ist.

        Zu number vs. string: Objekte in JS haben strings als Keys, selbst wenn du mit einer Zahl drauf zugreifst:

        "states": {
              "0": "ALL ON not active, ALL OFF not active",
              "1": "ALL ON not active, ALL OFF active",
              "2": "ALL ON active, ALL OFF not active",
              "255": "ALL ON active, ALL OFF active"
            }
        

        Deswegen ist bei Record<string, ...> auch der Zugriff mit numerischen Keys möglich:
        https://www.typescriptlang.org/play?#code/MYewdgzgLgBAZiEAuGAlApqATgEwDzRYCWYA5gDQwBGiANugIZgB8MAvDAN4C+A3AFAIQAbQBEARlEBddjChYArugFDh4mR3lLeQA


        Zweitens: Bist du gerade nicht eher beim Skripten im Skript-Adapter? ==> https://github.com/ioBroker/ioBroker.javascript/blob/master/lib/javascript.d.ts

        Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

        N 1 Antwort Letzte Antwort
        0
        • AlCalzoneA Offline
          AlCalzoneA Offline
          AlCalzone
          Developer
          schrieb am zuletzt editiert von
          #4

          @noox oder willst du erreichen, dass beim createState mit vorhandenem common.states geprüft wird, ob der übergebene Wert dazu passt? Das könnte gehen - aber nur, wenn der zu setzende Wert genau genug bekannt ist.

          Für die Nutzung mit Variablen steht man schon wieder vor dem Problem, dass irgendwie die Brücke zur State-Definition geschlagen werden muss - und das ohne den Code auszuführen.

          Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

          1 Antwort Letzte Antwort
          0
          • paul53P paul53

            @noox
            common.states ist als Objekt mit einer Anzahl diskreter Werte (false/true oder 0/1/2/...) denen Zustandstexte zugewiesen werden, definiert. Was soll daran geändert werden ?

            N Offline
            N Offline
            noox
            schrieb am zuletzt editiert von noox
            #5

            @paul53 said in TypeScript und common.states (Record<string, string>):

            @noox
            common.states ist als Objekt mit einer Anzahl diskreter Werte (false/true oder 0/1/2/...) denen Zustandstexte zugewiesen werden, definiert. Was soll daran geändert werden ?

            Die common.states können in JS ja auf verschiedensten Weise angegeben werden. In TypeScript ist zumindest die Definition mit Record<string, string> restriktiver. Mir geht's nicht um eine Änderung, sonder eher um eine Best Practice.

            Mir ist nämlich mehrmals aufgefallen, dass ich mich verhaut habe. Z.B. habe ich einen Record standardmäßig definiert. Man darf aber dann nicht den Fehler machen, den State mit dem Wert stateValues1.stateA (vom Record) zu erstellen oder auf diesen zu setzen. Weil stateValues1.stateA liefert den Value ('Status A') und nicht den Key. Fehler bekommt man allerdings keinen - d.h. wenn man es durchgängig macht, funktioniert es sogar.

            1 Antwort Letzte Antwort
            0
            • AlCalzoneA AlCalzone

              @noox sagte in TypeScript und common.states (Record<string, string>):

              So ganz happy bin ich mit dem Record nicht, weil man zumindest im einfachsten Fall mit Zeichenketten herum hantiert, wo natürlich schnell mal ein Tippfehler passieren kann.

              Tippfehler abfangen in Objekten, die an Funktionen übergeben werden (wie der common-Teil an sich), funktioniert nur, wenn die Form des Objekts vorher bekannt ist. Im Falle von common.states ist das nicht gegeben, da hier jeder erdenklicher Key erlaubt ist.

              Zu number vs. string: Objekte in JS haben strings als Keys, selbst wenn du mit einer Zahl drauf zugreifst:

              "states": {
                    "0": "ALL ON not active, ALL OFF not active",
                    "1": "ALL ON not active, ALL OFF active",
                    "2": "ALL ON active, ALL OFF not active",
                    "255": "ALL ON active, ALL OFF active"
                  }
              

              Deswegen ist bei Record<string, ...> auch der Zugriff mit numerischen Keys möglich:
              https://www.typescriptlang.org/play?#code/MYewdgzgLgBAZiEAuGAlApqATgEwDzRYCWYA5gDQwBGiANugIZgB8MAvDAN4C+A3AFAIQAbQBEARlEBddjChYArugFDh4mR3lLeQA


              Zweitens: Bist du gerade nicht eher beim Skripten im Skript-Adapter? ==> https://github.com/ioBroker/ioBroker.javascript/blob/master/lib/javascript.d.ts

              N Offline
              N Offline
              noox
              schrieb am zuletzt editiert von
              #6

              @AlCalzone said in TypeScript und common.states (Record<string, string>):

              Tippfehler abfangen in Objekten, die an Funktionen übergeben werden (wie der common-Teil an sich), funktioniert nur, wenn die Form des Objekts vorher bekannt ist. Im Falle von common.states ist das nicht gegeben, da hier jeder erdenklicher Key erlaubt ist.

              Mir geht's darum, dass ich den Wert eines Status dann in einer vernünftigen Form habe - eben z.B. ein Enum. Damit dann die weitere Fehleranfälligkeit geringer ist. Dass die States alle möglichen Werte akzeptieren, finde ich nicht so tragisch - insbesondere wenn ich eben vorher mit sauberen Typen bzw. Enums arbeiten kann, dann ist die Wahrscheinlichkeit eh gering, hier einen Fehler zu machen.

              Zu number vs. string: Objekte in JS haben strings als Keys, selbst wenn du mit einer Zahl drauf zugreifst:
              Deswegen ist bei Record<string, ...> auch der Zugriff mit numerischen Keys möglich:

              Damit ich die Enums verwenden kann, hatte ich den Record als Record<MyEnum, string> definiert. Allerdings vergessen, common.type von string auf number zu ändern. createState('id', MyEnum.enumValA, false, {...}); funktioniert trotzdem. setState('id', MyEnum.enumValA); funktioniert auch, liefert allerdings eine Warnung bei der Ausführung. Was ja eigentlich auch OK ist, weil der Enum-Wert ja eine number ist.

              Prinzipiell hat man einige Freiheiten bei den States, aber es gibt halt auch ein paar Fallen. Daher möchte ich mir halt eine Best Practice-Methode zurechtlegen. Aber denke, ich bleib bei Variante 3 mit dem Enum.

              Zweitens: Bist du gerade nicht eher beim Skripten im Skript-Adapter? ==> https://github.com/ioBroker/ioBroker.javascript/blob/master/lib/javascript.d.ts

              Danke!

              1 Antwort Letzte Antwort
              0
              • AlCalzoneA Offline
                AlCalzoneA Offline
                AlCalzone
                Developer
                schrieb am zuletzt editiert von
                #7

                Das was du (glaube ich) vor hast, kann man nicht statisch prüfen. Der Aufruf von setState('id', MyEnum.enumValA); hat für TypeScript nichts mit createState('id', MyEnum.enumValA, false, {...}); zu tun.

                Außerdem kommt wie gesagt noch dazu, dass Record<string, string> ist bei den Keys auch flexibel ist - number geht aus Kompatibilitätsgründen zu JavaScript auch. Und Enums mit TypeChecking ist auch eher so lala.
                Wenn du was findest, was für dich funktioniert, dann ists gut. Aber ich fürchte das global zu nutzen wird schwierig.

                Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                1 Antwort Letzte Antwort
                0
                Antworten
                • In einem neuen Thema antworten
                Anmelden zum Antworten
                • Älteste zuerst
                • Neuste zuerst
                • Meiste Stimmen


                Support us

                ioBroker
                Community Adapters
                Donate

                692

                Online

                32.5k

                Benutzer

                81.7k

                Themen

                1.3m

                Beiträge
                Community
                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                ioBroker Community 2014-2025
                logo
                • Anmelden

                • Du hast noch kein Konto? Registrieren

                • Anmelden oder registrieren, um zu suchen
                • Erster Beitrag
                  Letzter Beitrag
                0
                • Home
                • Aktuell
                • Tags
                • Ungelesen 0
                • Kategorien
                • Unreplied
                • Beliebt
                • GitHub
                • Docu
                • Hilfe