Search code examples
typescriptnpmyarnpkgmonaco-editorlanguage-server-protocol

editor.IStandaloneCodeEditor' is not assignable to parameter of type 'monaco.editor.IStandaloneCodeEditor'


in order to use monaco in below source code I did install below package but I'm getting that type error. Why is that and how can I fix that?

package:

npm i monaco-editor

I'm using this command:

yarn install

the package file looks like this:

{
  "private": true,
  "name": "node-example",
  "version": "0.13.0",
  "dependencies": {
    "@codingame/monaco-jsonrpc": "^0.3.1",
    "express": "^4.15.2",
    "file-loader": "^4.3.0",
    "monaco-editor": "^0.27.0",
    "monaco-editor-core": "^0.22.3",
    "monaco-editor-webpack-plugin": "^4.1.2",
    "monaco-languageclient": "^0.13.0",
    "normalize-url": "^2.0.1",
    "reconnecting-websocket": "^3.2.2",
    "request-light": "^0.2.2",
    "vscode-json-languageservice": "^4.0.2",
    "vscode-languageserver": "7.0.0",
    "vscode-uri": "^3.0.2",
    "vscode-ws-jsonrpc": "^0.2.0",
    "ws": "^5.0.0"
  },
  "scripts": {
    "prepare": "yarn run clean && yarn run build",
    "compile": "tsc",
    "watch": "tsc -w",
    "clean": "rimraf lib",
    "copy": "cp src/index.html lib/index.html",
    "build": "yarn run compile && webpack && yarn run copy",
    "start": "node lib/server.js",
    "start:ext": "node lib/server.js --external"
  },
  "devDependencies": {
    "webpack-cli": "^4.8.0"
  }
}

And this the error I'm getting:

src/client.ts:32:24 - error TS2345: Argument of type 'import("path/to/project/monaco-languageclient/example/node_modules/monaco-editor/esm/vs/editor/editor.api").editor.IStandaloneCodeEditor' is not assignable to parameter of type 'monaco.editor.IStandaloneCodeEditor'.

this is the full source code:

import { listen, MessageConnection } from 'vscode-ws-jsonrpc';
import {
    MonacoLanguageClient, CloseAction, ErrorAction,
    MonacoServices, createConnection
} from 'monaco-languageclient';
import * as monaco from 'monaco-editor'
import normalizeUrl = require('normalize-url');
const ReconnectingWebSocket = require('reconnecting-websocket');

// register Monaco languages
monaco.languages.register({
    id: 'typescript',
    extensions: ['.ts'],
    aliases: ['TypeScript','ts','TS','Typescript','typescript']
})

// create Monaco editor
const value = `{
    "$schema": "http://json.schemastore.org/coffeelint",
    "line_endings": "unix"
}`;
const editor = monaco.editor.create(document.getElementById("container")!, {
    model: monaco.editor.createModel(value, 'typescript', monaco.Uri.parse('file:///abs/path/to/demo/ts/file.ts')),
    glyphMargin: true,
    theme: "vs-dark",
    lightbulb: {
        enabled: true
    }
});

// install Monaco language client services
MonacoServices.install(editor,{rootUri: "file:///abs/path/to/demo/ts"});

// create the web socket
const url = createUrl('ws://localhost:3000/ts')
const webSocket = createWebSocket(url);
// listen when the web socket is opened
listen({
    webSocket,
    onConnection: connection => {
        // create and start the language client
        const languageClient = createLanguageClient(connection);
        const disposable = languageClient.start();
        connection.onClose(() => disposable.dispose());
    }
});

function createLanguageClient(connection: MessageConnection): MonacoLanguageClient {
    return new MonacoLanguageClient({
        name: "Sample Language Client",
        clientOptions: {
            // use a language id as a document selector
            documentSelector: ['typescript'],
            // disable the default error handler
            errorHandler: {
                error: () => ErrorAction.Continue,
                closed: () => CloseAction.DoNotRestart
            }
        },
        // create a language client connection from the JSON RPC connection on demand
        connectionProvider: {
            get: (errorHandler, closeHandler) => {
                return Promise.resolve(createConnection(connection, errorHandler, closeHandler))
            }
        }
    });
}

function createUrl(path: string): string {
    return normalizeUrl(path);
}

function createWebSocket(url: string): WebSocket {
    const socketOptions = {
        maxReconnectionDelay: 10000,
        minReconnectionDelay: 1000,
        reconnectionDelayGrowFactor: 1.3,
        connectionTimeout: 10000,
        maxRetries: Infinity,
        debug: false
    };
    return new ReconnectingWebSocket(url, [], socketOptions);
}

Solution

  • The issue appears to be a conflict between the monaco namespace provided by monaco-editor and the namespace of the same name provided by monaco-editor-core. When both are installed as dependencies, TypeScript seems to assume that monaco.editor.IStandaloneCodeEditor is referring to the latter, which causes issues since the created monaco.editor is imported from the former.

    To resolve this, removing monaco-editor-core as a dependency fixes the confusion and uses the correct typings for monaco.editor.IStandaloneCodeEditor.