[Bug]: Type declaratons are broken with 9.x
I'm sure that
- [x] This issue is still present in the current beta version of this adapter
- [x] There is no other (open) issue with the same topic (use the search!)
- [x] This issue is not described in the adapter documentation / FAQ (read the docs!)
Script type
TS
The problem
The javascript.d.ts file contains broken references, for example iobJS.StringOrTranslated is referred to as ioBroker.StringOrTranslated.
This is probably an incomplete list of broken references:
- ioBroker.SettableState
- ioBroker.StateValue
- ioBroker.State
The reason I'm reporting here is that I manage my (TypeScript) scripts in a Git repository. I downloaded the type definitions to be able to compile locally and can use the ioBroker sandbox API in a type-safe way. Version 9's restructuring efforts appear to have broken the setup since javascript.d.ts now also loads types from a different file.
iobroker.current.log (in debug mode!)
No response
Version of nodejs
20
Version of ioBroker js-controller
7.0.7
Version of adapter
9.0.3
Please retest with 9.0.4 (in process)
Testing things does not require new releases. I assume the JS API didn't change with 9.x (at least no breaking changes were documented except for the removal of request). You can check whether the d.ts file is consistent by downloading it and opening it with VS Code:
$ wget -O target.d.ts https://raw.githubusercontent.com/ioBroker/ioBroker.javascript/master/src/lib/javascript.d.ts
$ code target.d.ts
You will essentially see the same errors as the TS compiler:
iobroker.d.ts:1563:20 - error TS2503: Cannot find namespace 'ioBroker'.
1563 initValue: ioBroker.StateValue,
and hundreds more.
If you have a better idea on how to get the ioBroker JS API into a project outside of the web UI then please let me know. Downloading the d.ts file into my project has served me well for years.
@agross
This error also prevents the Nspanel script from transpiling in the JavaScript adapter, so it's not just a problem for your use case.
@GermanBluefox with 7.0.6 not fixed
Normally tsconfig.json is used where you define in compilerOptions the "types": ["@iobroker/types"]
This is the Error:
script.js.common.PROD.NSPanel.NSPanel_1.NSPanel1_4_7_2_X: TypeScript compilation failed: await setStateAsync(NSPanel_Path + 'PageNavi', <iobJS.State>{ val: "{ pagetype: 'page', pageId: 0 }", ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', <iobJS.State>{ val: 8, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourDay', <iobJS.State>{ val: 7, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', <iobJS.State>{ val: 1, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourNight', <iobJS.State>{ val: 22, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(meanPower, <iobJS.State>{ val: meanConsumption, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(screensaverNotifyHeading, <iobJS.State>{ val: '', ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(screensaverNotifyText, <iobJS.State>{ val: '', ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(obj.id, <iobJS.State>{ val: obj.state.val, ack: true }); // ack new value ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_locales_json', <iobJS.State>{ val: JSON.stringify(response.data), ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_locales_service_json', <iobJS.State>{ val: JSON.stringify(response.data), ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', <iobJS.State>{ val: getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', <iobJS.State>{ val: getState(NSPanel_Path + 'Berry_Driver.onlineVersion').val, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', <iobJS.State>{ val: getState(NSPanel_Path + 'Display_Firmware.onlineVersion').val, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyHeading, <iobJS.State>{ val: Headline, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyHeadingColor, <iobJS.State>{ val: HeadlineColor, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyButton1Text, <iobJS.State>{ val: Button1, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyButton1TextColor, <iobJS.State>{ val: Button1Color, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyButton2Text, <iobJS.State>{ val: Button2, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyButton2TextColor, <iobJS.State>{ val: Button2Color, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifySleepTimeout, <iobJS.State>{ val: Timeout, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyInternalName, <iobJS.State>{ val: InternalName, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyLayout, <iobJS.State>{ val: Layout, ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(popupNotifyText, <iobJS.State>{ val: [formatDate(getDateObject(new Date().getTime()), 'TT.MM.JJJJ SS:mm:ss'), '\r\n', '\r\n', Text].join(''), ack: false }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_ipAddress', <iobJS.State>{ val: get_current_tasmota_ip_address(), ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.onlineVersion', <iobJS.State>{ val: TasmotaVersionOnline, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', <iobJS.State>{ val: JSON.parse(JSON.stringify(response.data)).nlui_driver_version, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', <iobJS.State>{ val: tasmoVersion, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Uptime', <iobJS.State>{ val: Tasmota_JSON.StatusPRM.Uptime, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Version', <iobJS.State>{ val: Tasmota_JSON.StatusFWR.Version, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Hardware', <iobJS.State>{ val: TasmotaHardware[0] + '\r\n' + TasmotaHardware[1], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.AP', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.AP, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.SSId', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.SSId, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.BSSId', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.BSSId, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Channel', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.Channel, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Mode', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.Mode, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.RSSI', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.RSSI, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Signal', <iobJS.State>{ val: Tasmota_JSON.StatusSTS.Wifi.Signal, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Tasmota.Product', <iobJS.State>{ val: 'SONOFF NSPanel', ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Berry_Driver.onlineVersion', <iobJS.State>{ val: BerryDriverVersionOnline, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', <iobJS.State>{ val: NSPanelVersion, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Display_Firmware.onlineVersion', <iobJS.State>{ val: desired_display_firmware_version, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', <iobJS.State>{ val: split[2], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Display_Firmware.currentRelease', <iobJS.State>{ val: split[4], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'NSPanel_Version', <iobJS.State>{ val: split[3], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', <iobJS.State>{ val: tft_version, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.HUE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.HUE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.RED').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.RED').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.CIE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.CIE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.RGB').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(pageItem.id + '.TEMPERATURE').ts < getState(pageItem.id + '.RGB').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. setState(popupNotifyInternalName, <iobJS.State>{ val: words[2], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. setState(popupNotifyAction, <iobJS.State>{ val: true, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. setState(popupNotifyInternalName, <iobJS.State>{ val: words[2], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. setState(popupNotifyAction, <iobJS.State>{ val: false, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.HUE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.HUE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.RED').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.RED').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.RGB').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.RGB').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.CIE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. if (getState(id + '.TEMPERATURE').ts < getState(id + '.CIE').ts) { ^ ERROR: Property 'ts' does not exist on type 'AbsentState | TypedState<any>'. Property 'ts' does not exist on type 'TypedState<any>'. unsubscribe(value); ^ ERROR: Argument of type 'unknown' is not assignable to parameter of type 'string | RegExp | string[]'. await setStateAsync(NSPanel_Path + 'Sensor.Time', <iobJS.State>{ val: dateTime[0] + '\r\n' + dateTime[1], ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Sensor.TempUnit', <iobJS.State>{ val: '°' + Tasmota_Sensor.TempUnit, ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Sensor.ANALOG.Temperature', <iobJS.State>{ val: parseFloat(Tasmota_Sensor.ANALOG.Temperature1), ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. await setStateAsync(NSPanel_Path + 'Sensor.ESP32.Temperature', <iobJS.State>{ val: parseFloat(Tasmota_Sensor.ESP32.Temperature), ack: true }); ^ ERROR: Namespace 'global.iobJS' has no exported member 'State'. val: iobJS.StateValue; ^ ERROR: 'global.iobJS' has no exported member named 'StateValue'. Did you mean 'StateACL'? val: iobJS.StateValue; ^ ERROR: 'global.iobJS' has no exported member named 'StateValue'. Did you mean 'StateACL'?
Adding:
import '@iobroker/types';
also does not improve the situation.
In version 8.9.2 everything runs perfectly!
Normally tsconfig.json is used where you define in compilerOptions the "types": ["@iobroker/types"]
Are you sure this will work? @iobroker/types does not define the JavaScript sandbox API, does it? After installing and referencing the package, I still have errors:
error TS2694: Namespace 'global.iobJS' has no exported member 'State'.
77 state: current as iobJS.State,
After changing these occurrences to ioBroker.State, there is another case that I am unsure how to solve. Previously, I was able to call getState and check if the requested state exists:
var s = getState(object)
if (s.notExist) { }
This no longer works because only AbsentState defines notExists. Do you expect us to write custom type guards from now on?
@GermanBluefox any new here ?
v9.0.10 Es sind leider noch immer Fehler in der Definition
state sollte imho auch ts, ack und lc enthalten,
Edit: bei on() fehlt im datenpunkt parameter das from
Please try 9.0.11
What's the suggestion for notExist?
What's the suggestion for
notExist?
Auch in der 9.0.11 - und somit wahrscheinlich auch in der 9.0.12 sind noch Fehler
Wie mit @Armilar extern besprochen, sind die Fehler im Skript zu finden und behoben. Ich hab bis jetzt keine weiteren Fehler gefunden.
Von mir ein 👍
But in 9.0.12
When will this version be released in the beta repository?
When will this version be released in the beta repository?
Probably never.