NEWS
Typprüfung mit javascript.d.ts
-
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.
-
Kannst du mal ein Minimalbeispiel (Ordnerstruktur mit Dateiinhalten) erzeugen, damit ich dein Problem nachvollziehen kann? `
Und ein Minimalbeispiel für eine fehlende Meldung bei fehlender Deklaration:
filename="Beispiel Typeprüfung 2.png" index="0">~~
-
Hier die Erklärung für das Verhalten.
https://www.typescriptlang.org/docs/han … dules.html
` > Starting with ECMAScript 2015, JavaScript has a concept of modules. TypeScript shares this concept.Modules are executed within their own scope, not in the global scope; this means that variables, functions, classes, etc. declared in a module are not visible outside the module unless they are explicitly exported using one of the export forms. Conversely, to consume a variable, function, class, interface, etc. exported from a different module, it has to be imported using one of the import forms.
Modules are declarative; the relationships between modules are specified in terms of imports and exports at the file level.
Modules import one another using a module loader. At runtime the module loader is responsible for locating and executing all dependencies of a module before executing it. Well-known modules loaders used in JavaScript are the CommonJS module loader for Node.js and require.js for Web applications.
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well). `
Da kannst du leider fast nichts dran ändern, das ist eine TypeScript-Eigenheit. Du kannst aber erzwingen, dass eine JS-Datei als Modul gehandhabt wird. Das geht fast genauso wie ich in der .d.ts-Datei gemacht habe, mit einem Dummy-Import (bzw. require).
-
Hier die Erklärung für das Verhalten.
Da kannst du leider fast nichts dran ändern, das ist eine TypeScript-Eigenheit. Du kannst aber erzwingen, dass eine JS-Datei als Modul gehandhabt wird. Das geht fast genauso wie ich in der .d.ts-Datei gemacht habe, mit einem Dummy-Import (bzw. require).
Unbenannt.PNG `
Ich danke Dir für Deine Mühe und Geduld! Wahnsinn!
Vor allem für die mitgelieferte Erklärung :!: :idea:
Werde dass dann mit dem "require("fs");" Dummy umgehen.
Du bist doch bestimmt tausendmal intensiver mit vscode unterwegs.
Organisierst Du Dein Skriptverzeichnis anders oder nutzt Du eine Namensgebung, mit der das nicht passieren kann?
Ich habe das Gefühl, bei mir ist noch viel Luft nach oben :mrgreen: