George Kemp
George Kemp

Reputation: 631

Adding Typescript Type Declarations to Monaco Editor

I have a Monaco editor which the user inputs custom javascript code. Within this Monaco Editor they can use Lodash functionality. I want to be able to give them the intellisense / code completion for lodash, by including the type definitions.

I've seen a few answers relating to adding custom declarations, but none that are including a whole 3rd party libraries declarations. Has anybody had experience with this.

This is what I have so far. Then below I create the editor, similar to the example in the documentation.

monaco.languages.typescript.typescriptDefaults.addExtraLib("", "./../../types/lodash/index.d.ts");

Upvotes: 8

Views: 15184

Answers (3)

Lukas Bach
Lukas Bach

Reputation: 3919

I'd like to add the package monaco-editor-auto-typings as an option. Disclaimer: I'm the developer of that package.

It continuously scans code entered in the monaco editor, detects imports and automatically loads the declaration files from UnPkg.

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { AutoTypings, LocalStorageCache } from 'monaco-editor-auto-typings';

const val = `
import React from 'react';
React.useEffect(0); // Type Error!
`;

// Create monaco editor instance
const editor = monaco.editor.create(document.getElementById('root')!, {
  model: monaco.editor.createModel(val, 'typescript'),
});

// Initialize auto typing on monaco editor. Imports will now automatically be typed!
const autoTypings = AutoTypings.create(editor, {
  sourceCache: new LocalStorageCache(), // Cache loaded sources in localStorage. May be omitted
  // Other options...
});

You can explore how it works in the demo.

Upvotes: 8

cdrini
cdrini

Reputation: 1096

(Copied from my GH Gist: https://gist.github.com/cdrini/9de507f6ac19da30fd27c5f618783b31 )

Well that was a headache! This is certainly not an elegant solution, but it works. Hopefully someone can use these notes to save themselves a bunch of time.

Known issues:

  • This does not scale easily to any other library
  • Requires some internal knowledge of lodash's types library which might break on a lodash update

Add raw-loader and @types/lodash

npm install --save-dev @types/lodash raw-loader

(as of writing, these are at 4.14.162 and 4.0.2, respectively)

Import and register the .d.ts files

Looking at @types/lodash/index.d.ts, copy all the common references and import them. :

import LODASH_index from '!raw-loader!@types/lodash/index.d.ts';
import LODASH_common from '!raw-loader!@types/lodash/common/common.d.ts';
import LODASH_array from '!raw-loader!@types/lodash/common/array.d.ts';
import LODASH_collection from '!raw-loader!@types/lodash/common/collection.d.ts';
import LODASH_date from '!raw-loader!@types/lodash/common/date.d.ts';
import LODASH_function from '!raw-loader!@types/lodash/common/function.d.ts';
import LODASH_lang from '!raw-loader!@types/lodash/common/lang.d.ts';
import LODASH_math from '!raw-loader!@types/lodash/common/math.d.ts';
import LODASH_number from '!raw-loader!@types/lodash/common/number.d.ts';
import LODASH_object from '!raw-loader!@types/lodash/common/object.d.ts';
import LODASH_seq from '!raw-loader!@types/lodash/common/seq.d.ts';
import LODASH_string from '!raw-loader!@types/lodash/common/string.d.ts';
import LODASH_util from '!raw-loader!@types/lodash/common/util.d.ts';
  • Note: Vetur will complain in VS Code about importing .d.ts files, but won't error.

Then register them into monaco (wherever monaco is in your project):

window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_index, '@types/lodash/index.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_common, '@types/lodash/common/common.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_array, '@types/lodash/common/array.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_collection, '@types/lodash/common/collection.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_date, '@types/lodash/common/date.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_function, '@types/lodash/common/function.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_lang, '@types/lodash/common/lang.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_math, '@types/lodash/common/math.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_number, '@types/lodash/common/number.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_object, '@types/lodash/common/object.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_seq, '@types/lodash/common/seq.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_string, '@types/lodash/common/string.d.ts');
window.monaco?.languages.typescript.javascriptDefaults.addExtraLib(LODASH_util, '@types/lodash/common/util.d.ts');

Note:

  • The file names matter here (somehow); removing the .d.ts extension causes them to break.

References/External Links

Open Questions

  • What does the filename actually do? Also, what are the protocol prefixes for?

Upvotes: 8

dynamo
dynamo

Reputation: 1153

See this as an example and the apis. you should pass the content of the .d.ts file as the first argument

monaco.languages.typescript.typescriptDefaults.addExtraLib(content, "")

check this demo of how pass arguments

Upvotes: 6

Related Questions