Monaco clarification

Yes. No difference. I even loaded the new default settings.js and amended it to match the existing to see if there was something there but no change (that was on the Pi with the official upgrade command)

The ace editor still works OK as I reverted to check

@Buckskin Do you have another computer/laptop on your network that you can try accessing the faulty node-red installs (using http://IP:port) ?

Alternatively, if you can present your instance to the internet (node-red-contrib-ngrok can do this safely and easily) then PM me the URL & password - I'll see if your install works on my machine.

Hi Steve. Tried it on another PC, same - keyboard does not work.

I have installed node-red-contrib-ngrok and will try and work out the rest

Well that is jolly annoying. I have no idea how to PM and so far I haven't found anything to explain how (either that or I am just very slow)

Late update:

I have just installed on another pi (no previous NR);
Node-red v1.35 using normal bash script (node.js v14)
Node-red v2 using update install

and Monaco works on that NR instance. So, it would seem that there is possibly an installed node on my existing systems that is causing the problem. I will just have to install them on the new system one at a time until something falls over.

I have found the culprit. It is the node-red-contrib-zigbee2mqtt node. When I remove it the editor works as expected. That is a bit of a nuisance :unamused:

Is there an easy way to update the version of Javascript that is used for error checking.

A couple of examples :
a comma after the last property in an Object or Array is flagged as an error, which it isn't anymore
the 'options' in Intl.DateTimeFormat are flagged as invalid string type

Other than that, using Monaco is certainly improving the way I document my code :grinning:

Can you post an example/sample of code please?

My bad on the comma issue, I need to check my code more carefully - apologies, it DOES allow a final comma.

const UK_TIME_OPTIONS = { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false };

function UKTime(dirtyDate) {
    const date = new Date(dirtyDate);

    return date.toLocaleTimeString('en-GB', UK_TIME_OPTIONS);


This problem also crops up with Intl.DateTimeFormat

The error shown is;

Argument of type '{ hour: string; minute: string; second: string; hour12: boolean; }' is not assignable to parameter of type 'DateTimeFormatOptions'.
Types of property 'hour' are incompatible.
Type 'string' is not assignable to type '"2-digit" | "numeric"'.(2345)

Yes. That one is odd.

I'm looking into it.

Cheers. Sorry about my confusion with the comma, teach me to be more careful about using ; instead of ,

Easily done. I stopped using ; in Node/JS some years ago though and I always use trailing comma's.

This is quite odd - possibly a bug in typescript or monaco?

If I put the options directly into the call, it doesn't complain

For now, the solution is to disable error 2345. I will add that to the src.

I'll also post this on the monaco repo - see what they say.

Thank you, saves having to add // @ts-ignore . Be interesting to see the reply.

An official answer...

The problem occurs because .weekday is required to be one of "long" | "short" | "narrow" but assigning the object literal to a variable first, with no further context, causes it to be widened to string , which TS then can't verify is compatible when you pass it to the function later. Passing the object literal directly works because contextual typing prevents the widening (i.e. TS can verify on the spot that you're passing a compatible string literal).

And a work around - use a JSdoc @type hint...

/** @type {Intl.DateTimeFormatOptions} */
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };


Thanks for that, appreciate you taking the time (although I have had to put the @type in front of every DateTimeFormatOption const, and I have a few.) :grin:

I must admit to not quite understanding because to me 'long' is a string but I guess it is to do with how TS identifies a valid entry (obviously not by checking the value as a string)

For anyone else looking at this, note that the /** at the beginning is mandatory (/* does not work)

Errm, sorry to be a pain but I have another one for you

class DeviceModel {
    static #deviceModelList = []

'static' modifier cannot be used with a private identifier.(18019)

This is a stage 3 proposal according to MDN, but if I // @ts-ignore it works. (it was something that I thought was a good idea so I tried it). It may be that this hasn't worked its way into a proper release yet

I'm not sure if you are actually willing to look at these niggles, so if not please let me know and I will stop pestering you. It's not as if they cannot be got round..

1 Like

That's because Monaco uses JSDoc for type hinting.

I dont think it is unreasonable. According to MDN, nodejs 12.0.0 has support for this since monaco is for node-red 2.0.0 and node-red 2.0.0 states a minimum of nodejs 12.0.0. I will add this to the draft PR for next node-red beta.

Click to show working demo

Visit monaco playground & paste the below code into the left-hand editor, then click the run button

// validation settings
    noSemanticValidation: false,
    noSyntaxValidation: false,

// compiler options
    target: monaco.languages.typescript.ScriptTarget.ESNext,
    allowNonTsExtensions: true,
    useDefineForClassFields: true //permit class Static fields with private name to have initializer

var jsCode = `class A {
      static #statPriv  = 4;
      #priv = 123;
      t = 345;
      getValues() {
            return [this.t, this.#priv, A.#statPriv];
      #setValues(statPriv, priv, t) {
            A.#statPriv = statPriv;
            this.#priv = priv;
            this.t = t;
      constructor() {
const aA = new A();
aA.t = 999;
const v = aA.getValues();
// aA.#priv = 999; //error
// A.#statPriv = 999; //error
// aA.#setValues(); //error`;

monaco.editor.create(document.getElementById('container'), {
    value: jsCode,
    language: 'javascript'

Cheers Steve. Good to know I'm not chasing rainbows