I am trying to provide intellisense / code completion into a javascript editor using the Monaco editor. The code needs to be valid javascript, not typescript.
Given some user entered script like this:
function onMyEvent(event)
{
event.someProperty
}
I want to provide code completion on the event parameter, which is a typescript class I have the t.ds of, and can infer at runtime.
Ideally, I would just like to tell Monaco that the type of event
is SomeEventClass
, and let it do the rest.
Even if that meant adding type hints to the script. But I can't see how to do that.
I tried using JSDoc syntax and various combinations in the user script, but it looks like thats blocked FTB see:
https://github.com/Microsoft/monaco-editor/issues/203
and
Adding JavaScript type hints for VSCode/Monaco Intellisence
I also tried injecting a dynamic d.ts, as per https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-javascript-defaults
But declaring the function didn't seem to mean anything to the editor. Declaring a new class definitely worked, I just can't work out how to tell Monaco that event
in that function is a specific type.
I can see the registerCompletionItemProvider API, but that doesn't give you any context of where the item was declared etc, and also doesn't let me automatically use the d.ts file that I want to.
The Monaco Editor is the code editor that powers VS Code. A good page describing the code editor's features is here. It is licensed under the MIT License and supports Edge, Chrome, Firefox, Safari and Opera. The Monaco editor is not supported in mobile browsers or mobile web frameworks.
The easiest way to use the react-monaco-editor with create-react-app is to use the react-app-rewired project. For setting it up, the following steps are required: Install react-app-rewired : npm install -D react-app-rewired. Replace react-scripts by react-app-rewired in the scripts section of your packages.
You'll need to copy the files from node_modules/monaco-editor/min/vs to your preferred location of choice. Since I'm using ASP.NET Core, I use gulp to copy the files from node_modules to wwwroot/js/vs . Here is condensed sample of how to set up the Monaco Editor, since I could not find a quick start elsewhere.
As of Monaco version 0.90, since https://github.com/Microsoft/monaco-editor/issues/203 has been fixed, you can add achieve this partially if you use JSDoc in the editing code.
For this code in the left side of the Monaco playgound:
// validation settings
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
noSemanticValidation: true,
noSyntaxValidation: false
});
// compiler options
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.ES6,
allowNonTsExtensions: true,
allowJs: true
});
// extra libraries
monaco.languages.typescript.javascriptDefaults.addExtraLib([
'declare class SomeEventType {',
' /**',
' * Heres the doco for someProperty',
' */',
' someProperty: string',
'}',
].join('\n'), 'filename/facts.d.ts');
var jsCode = [
'"use strict";',
'',
"/**",
" * @param {SomeEventType} event",
" */",
"function onMyEvent(event) {",
"",
"}"
].join('\n');
monaco.editor.create(document.getElementById("container"), {
value: jsCode,
language: "javascript"
});
Means that the editor can now interpret the event parameter as a SomeEventType:
Put this in the editor in the Monaco Playground:
monaco.editor.create(document.getElementById("container"), {
value: "function hello() {\n\talert('Hello world!');\n}",
language: "typescript"
});
const fact = `declare function onMyEvent(event: string): void;
`;
const factFilename = 'myCustomNamespace1';
this.monaco.languages.typescript.typescriptDefaults.addExtraLib(fact, factFilename);
Now when you type onMyEvent
in the right-hand pane, you'll get
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With