NEWS
Typprüfung mit javascript.d.ts
-
Thread für Fragen zur Typprüfung mit der Datei javascript.d.ts
siehe: https://github.com/ioBroker/ioBroker.ja … cript.d.ts
Fehlermeldung bei id-Array in Subscription -> on()
on([id1,id2], function (dp) { log("test"); });
-
getSubscriptions ist in javascript.d.ts nicht definiert.
Issue auf Github aufgemacht:
-
Bei der eigenen globalen Funktion event() meckert die Typprüfung.
Ich habe keine Ahnung warum.
In der javascript.d.ts gibt es keine Funktion mit dem Namen event().
Hat jemand zufällig eine Idee?
-
1. und 2. werden gleich gefixt. - EDIT: https://github.com/ioBroker/ioBroker.javascript/pull/97
zu 3.: TypeScript bzw. damit geprüftes JavaScript kennen verschiedene Target-Libraries, d.h. EcmaScript-Versionen und Umgebungen. Standardmäßig enthält diese Auflistung das Browser-DOM, in welchem
event
definiert ist für Benutzerinteraktionen etc… Das kannst du abschalten mit einer Konfigurationsdatei "jsconfig.json" im Arbeitsordner von von VSCode:{ "compilerOptions": { "lib": [ "es5" ] } }
Je nach NodeJS-Version kannst du auch eine höhere Lib verwenden, z.b. "es6" für NodeJS 4+
-
1. und 2. werden gleich gefixt. - EDIT: https://github.com/ioBroker/ioBroker.javascript/pull/97
zu 3.: TypeScript bzw. damit geprüftes JavaScript kennen verschiedene Target-Libraries, d.h. EcmaScript-Versionen und Umgebungen. Standardmäßig enthält diese Auflistung das Browser-DOM, in welchem
event
definiert ist für Benutzerinteraktionen etc… Das kannst du abschalten mit einer Konfigurationsdatei "jsconfig.json" im Arbeitsordner von von VSCode:{ "compilerOptions": { "lib": [ "es5" ] } }
Je nach NodeJS-Version kannst du auch eine höhere Lib verwenden, z.b. "es6" für NodeJS 4+ `
danke für die ausführliche Erklärung!
da wäre ich im Leben nicht drauf gekommen [emoji51]
überlege, ob ich die Prüfung ausschalte oder die globale Funktion umbenenne.
wer weiß, ob die Prüfung nach TS doch mal benötigt wird.
Gesendet von iPhone mit Tapatalk
-
Abschalten war vllt das falsche Wort, vielmehr sagst du dem Type-Checker dass dein Code in einer EcmaScript 5 (bzw. 6) Runtime (d.h. NodeJS) läuft und nicht in einem Browser. Willst du den Browser einschließen, einfach "dom" in die Liste hinzufügen.
-
mit einer Konfigurationsdatei "jsconfig.json" im Arbeitsordner von von VSCode:
{ "compilerOptions": { "lib": [ "es5" ] } }
Je nach NodeJS-Version kannst du auch eine höhere Lib verwenden, z.b. "es6" für NodeJS 4+ `
Da wollte ich eine positive Rückmeldung geben… aber leider wird immer noch die Meldung "Doppelter Bezeichner" angezeigt.
Ich habe im Arbeitsbereich im Ordner .vscode die Datei jsconfig.json neu angelegt.
In der Variante (mit es5 und es 6 probiert (ich verwende node.js 8):
{ "compilerOptions": { "lib": [ "es6" ] } }
Dann die Varianten es5 und es6 in dieser Variation:
(laut Doku vom vscode: https://code.visualstudio.com/docs/languages/jsconfig)
{ "compilerOptions": { "target": "es6" } }
Leider ohne Erfolg.
-
Ich habe im Arbeitsbereich im Ordner .vscode die Datei jsconfig.json neu angelegt. `
Ich bin mir recht sicher, die muss in den Hauptordner bzw. dorthin wo auch die JS-Dateien liegen. Die Einstellungen werden kaskadiert und können in Unterordnern überschrieben werden. -
Ich bin mir recht sicher, die muss in den Hauptordner bzw. dorthin wo auch die JS-Dateien liegen. Die Einstellungen werden kaskadiert und können in Unterordnern überschrieben werden. `
Danke! Das war es. Damit funktioniert es mit Deiner Variante.
-
Deklaration der Konstante name fehlt in der javascript.d.ts.
const name: string;
-
Was tut die?
-
-
Eine Frage an die Typprüfung Profis…
Es hat bis jetzt alles wunderbar funktioniert und die Vorteile einer aktivierten Typprüfung sind wirklich greifbar.
Bei einem Skript habe ich nun allerdings ein Verhalten, welches ich mir nicht erklären kann.
Einmal wurde die Benutzung einer Variable nicht angemeckert, die noch nicht definiert war.
Im zweiten Fall ist es genau umgekehrt. Eine deklarierte Variable wird als nicht vorhanden angezeigt.
Hat jemand eine Idee, warum das so sein könnte.
1. Beispiel: fehlende Definition erzeugt keine Fehleranzeige:
// var logFarbig = true; // zum Test auskommentiert
Die Variable ist in anderen Skripten (in keine globalen, kein Skript mit Typdatei, ohne Zusammenhang) vorhanden und wird nicht angemeckert:
.
.
Der 2. Fall. Variable vorhanden, wird aber als fehlend angemeckert:
`var triggerArr = []; //... triggerArr.push("javascript."+instance+"."+pfad+listen[i]+".event"); //.. on({id:triggerArr,change:'any'}, function (obj) {` filename="triggerArr.png" index="0">~~ Als Typdatei habe ich die **~~[b]~~javascript.d.ts[/b]** von gestern aktiv, in der Arrays für Subscriptions enthalten sein müsste.[/i]
-
Einmal wurde die Benutzung einer Variable nicht angemeckert, die noch nicht definiert war.
Hat jemand eine Idee, warum das so sein könnte.
1. Beispiel: fehlende Definition erzeugt keine Fehleranzeige:
// var logFarbig = true; // zum Test auskommentiert ```` `
Bei der Deklaration mit var kann das vorkommen, das die Deklaration script übergreifender ist. Ist mir auch schon auf die Füße gefallen.
Nimm lieber let, das hat nur den lokalen scope.
Ich versuche mittlerweile alles nur noch mit let zu deklarieren (außer ich will bewusst den Scope vergrößern) und habe keine Probleme mehr.
let logFarbig = true;
Mit let kannst du die Gültigkeit einer Variablen auch nur auf einen Block eingrenzen. Also beispielsweise nur für eine for Schleife.
Bei deinem 2. Fall sehe ich erstmal kein Problem.
-
Bei der Deklaration mit var kann das vorkommen, das die Deklaration script übergreifender ist. Ist mir auch schon auf die Füße gefallen.
Nimm lieber let, das hat nur den lokalen scope.
Ich versuche mittlerweile alles nur noch mit let zu deklarieren (außer ich will bewusst den Scope vergrößern) und habe keine Probleme mehr.
let logFarbig = true; ```` `
Danke für den Tipp [emoji106], den ich dann ab jetzt beherzigen werde.
Komisch ist das schon. Kann doch nicht im Sinne des Erfinders sein [emoji15]
Gesendet von iPad mit Tapatalk
-
Das ist ja auch https://www.planningforaliens.com/blog/2016/04/11/why-js-development-is-crazy/
Hier ist eine Erklärung :
-
Das ist ja auch https://www.planningforaliens.com/blog/2016/04/11/why-js-development-is-crazy/
Hier ist eine Erklärung :
ja, javascript :?
Ich habe mir derweil auch eine Erklärung dazu angesehen https://developer.mozilla.org/de/docs/W … ements/let.
1:1 kann ich das dann nicht übernehmen. Umdenken ist angesagt.
Das andere Problem lag bei mir :roll:
Hatte "übersehen", dass ich das Array versehentlich innerhalb einer Funktion deklariert hatte.
Dann kann ich sie natürlich nicht an anderer Stelle im Skript verwenden. :lol:
Die Typeprüfung hat da richtig reagiert.
War wohl wg. dem 1. Punkt etwas sensibel. Der mich immer noch verwundert
-
Bei der Deklaration mit var kann das vorkommen, das die Deklaration script übergreifender ist. Ist mir auch schon auf die Füße gefallen.
Nimm lieber let, das hat nur den lokalen scope.
Ich versuche mittlerweile alles nur noch mit let zu deklarieren (außer ich will bewusst den Scope vergrößern) und habe keine Probleme mehr.
let logFarbig = true;
Mit let kannst du die Gültigkeit einer Variablen auch nur auf einen Block eingrenzen. Also beispielsweise nur für eine for Schleife. `
Unabhängig von der Möglichkeit let zu verwenden…
Ich bin der Meinung, dass sich das Verhalten von vscode vorher nicht so war.
Hat jemand eine Idee, wie ich verhindern kann, das vscode Variablen, die in unterschiedlichen Skripten deklariert werden anmeckert.
Die Skripte sind für sich eigenständig und haben nichts miteinander zu tun.
Ich verwende:
/// <reference path="../javascript.d.ts"> /// <reference path="../javascript-global.d.ts"> // @ts-check</reference></reference>
javascript.d.ts" für den Javascript Adapter
javascript-global.d.ts für meine eigenen globalen Funktionen
Gefühlt zeitgleich mit dem Problem werden nun meine globalen Funktionen bei der Typehilfe nicht mehr korrekt angezeigt.
Die Variablennamen werden angezeigt, aber nicht mehr die Beschreibung und die richtigen Typen (immer any, als z.B. string).
Ich vermute, es ist etwas in der javascript-global.d.ts. Sehe aber nicht, was es sein könnte.
! ````
import child_process = require("child_process");
! // tslint:disable:no-namespace
declare global {namespace iobGlobal {
! type loglevel = "debug2" | "debug1" | "debug" | "info" | "warn" | "error";
}
! // Logikwerte:
// ===========================================
/**
* true/false als Ergebnis ob der aktuelle Tag ein Arbeitstag ist
/
function arbeitstag(): boolean;
! /*
* true/false als Ergebnis ob der aktuelle Tag ein Urlaubstag ist
/
function urlaubstag(): boolean;
! /*
* true wenn die aktuelle Zeit im angegebenen Zeitraum liegt
* @param strLower Startzeit formatiert als hh:mm:ss
* @param strUpper Endzzeit formatiert als hh:mm:ss
/
function isTimeInRange(strLower:string, strUpper:string): boolean;
! // Werte ausgeben
// ===========================================
/*
* gibt den Wochentag (Montag, Dienstag, ...) als Text zurück
/
function wochentag(): string;
! /*
* Gibt das Delta zwischen einem im Datenpunkt gespeicherten
* Epoch Wert und der aktuellen Zeit formatiert zurück.
*
* Zum speichern einer Zeit in einen Datenpunkt kann die Funktion
* dateEpochNow() verwendet werden.
/
function deltazeit(datenpunkt:string): string;
! /*
* gibt das aktuelle Datum & die Zeit formatiert aus
* Defaultformat: "YYYY-MM-DD hh:mm:ss"
* @param format Format der Ausgabe, Format wie bei formateDate()
* @param msBool true: ms im Format .ms werden angehängt
/
function dateNow(format?:string,msBool?:boolean): string;
! /*
* Gibt die Anzahl der gefundenen Subscriptions zurück.
* Listet alle Subscriptions innerhalb der Javascript-Instanz auf, die dem Filter entsprechen, im Log auf.
* Defaultformat: "YYYY-MM-DD hh:mm:ss"
* @param scriptname (optional) "alle", "Name des Skripts", "FEQ", usw.
* @param level (optional) loglevel für logs, default: "info"
* // Filter (scriptname):
* --------------------
* sucht den String in den überwachten Datenpunkten der Javascript-Instanz
* und sucht den String in den Scriptnamen innerhalb der Javascript-Instanz
* keine Angabe -> Filter = "alle" (alle Subscriptions der Instanz)
*
* loglevel
* --------
* loglevel = "debug2" | "debug1" | "debug" | "info" | "warn" | "error"
*
* Beispiele:
* ----------
* prinSubs(); listet alle Subscriptions innerhalb der Javascript-Instanz auf
* prinSubs("alle"); listet alle Subscriptions innerhalb der Javascript-Instanz auf
* printSubs("Skriptname"); alle Subscriptions innerhalb des aufrufenden Scripts
* printSubs("FEQ"); alle Subscriptions, die im Script oder Objekt "FEQ" enthalten
/
function printSubs(scriptname?:string,level?:iobGlobal.loglevel): number;
! /*
* Gibt eine zufällige Zahl zwischen min und max zurück
* @param min kleinster möglicher Wert der Zufahlszahl
* @param max größter möglicher Wert der Zufahlszahl
/
function rand(min:number,max:number) : number;
! // Funktionen
// ===========================================
! /*
* Rundet eine Zahl auf die angegebenen Stellen
* @param wert Zahl, die gerundet werden soll
* @param stellen Anzahl der Stellen
/
function runden(wert: number, stellen: number): number;
! /*
* Ansage über den sayit Adapter
* @param text Ansage, die abgespielt werden soll
* @param vol (optional) Lautstärke der Ansage von 1-100
* @param instanz? (optional) ohne Angabe: default Instanz. Mit Angabe: sayit Instanz
*/
function sayit(text: string, vol?: number, instanz?: number): void;/** * formatiert eine Übergabe in Sekunden zu einem lesbaren String * @param sekunden Sekunden, die lesbar ausgegeben werden sollen */ function sek2txt(sekunden:number | string): string;
! /**
* Loglevel innerhalb eines Javascripts
* das Script muss am die Variable des gewünschten Loglevels definiert haben, z.B.:
* var loglevel = "info";
* @param logtext Text, der in der Logausgabe erscheinen soll
* @param level "debug2" | "debug1" | "debug" | "info" | "warn" | "error"
* @param color? (optional) ohne Angabe: vordefinierte Farbe für den level, mit Angabe: gültige html Farbe
* Rückgabe: verwendeter Loglevel zur Information
/
function logs(logtext:string,level:iobGlobal.loglevel,color?:string):string;
! /*
* Schreibt einen Text mit Zeitstempel in eine Logdatei
* Datei: /opt/iobroker/iobroker-data/scripts-logf.log
* var loglevel = "info";
* @param text Text, der mit einem Zeitstempel in die Logdatei geschrieben werden soll
/
function logf(text:string);
! function event(text: string, list?: string) : void;
! // Helfer:
// ===========================================
/*
* liefere Anzahl n nbsp in utf-8, wenn str nicht angegeben oder n-mal str
* @param n Anzahl von nbsp;, bzw. wenn str angegeben: ANzahl des Strings in str
* @param str (optional) String, welche n mal erzeugt wird
/
function fill(n:number,str?:string): string;
! /*
* gibt das aktuelle Datum in Epoch zurück
/
function dateEpochNow() : number;
! /*
* entfernt aus einem html String die html Tags
*/
function html2str(html:string) : number;
! // Workaround, Fehler in der ioBroker Typprüfung
// ===========================================
function getSubscriptions(): any;
! const name: string;
! }
! ````[EDIT]
Das Thema mit den anmecker der "doppelten" Variablen lässt sich soweit eingrenzen, dass immer das Skript zählt, welches sich in einer höheren Verzeichnisebene befindet.
Beispiel:
1. Ebene: var id = [""]
2. Ebene: var id = "";
Dann meckert die Typprüfung, das in der Datei in der 2. Ebene ein anderer Typ verwendet wird (string statt string[]).
Die Skripte haben so nichts miteinander zu tun.
kann man das eventuell mit einer Einstellung in vscode beeinflussen?
-
Ich kenne deinen Code nicht, aber eigentlich sollte VS in einer JS-Datei keine Variablen sehen, die einer anderen Datei definiert wurden, egal wo sie liegt.
Dazu gibt es zwei Ausnahmen:
1. export/import durch Module
2. im globalen scope deklarierte Variablen (declare global { … })
Ich vermute dein Problem liegt an Punkt 2. Wenn die Skripte nichts miteinander zu tun haben und beide im globalen scope eine Variable unterschiedlich definieren, musst du dein Projekt möglicherweise anders strukturieren. Z.b. mit den Arbeitsbereichen, aber die hab ich selbst noch nicht benutzt und weiß nicht wie sich das verhält.
Kannst du mal ein Minimalbeispiel (Ordnerstruktur mit Dateiinhalten) erzeugen, damit ich dein Problem nachvollziehen kann?
-
Kannst du mal ein Minimalbeispiel (Ordnerstruktur mit Dateiinhalten) erzeugen, damit ich dein Problem nachvollziehen kann? `
Am schnellsten als Bild:
Im Verzeichnis Skripte liegen:
javascript.d.ts
javascript-global.d.ts
test.js
Test/test2.js
Der Inhalt javascript-global.d.ts von steht zwei Posts drüber (viewtopic.php?f=21&t=11777&p=139202#p139128).
test.js
/// <reference path="javascript.d.ts"> /// <reference path="javascript-global.d.ts"> // @ts-check // Datei: Skripte/test.js var hallo = "text";</reference></reference>
Test/test2.js
`/// <reference path="../javascript.d.ts"> /// <reference path="../javascript-global.d.ts"> // @ts-check // Datei: Skripte/Test/test2.js var hallo = [];[/code]</reference></reference>` Das Problem ist nicht nur, dass ich die in unterschiedlichen Skripten die Variablen anders verwenden (mal als String, mal als any (leeres Array))... (da könnte ich mir noch mit einer anderen Namensgebung helfen - Bezeichnung der Variablen) ...schlimmer ist, dass in einem anderen Skript deklarierte Variablen im neuen Skript nicht angemeckert werden, wenn sie dort vergessen wurden.