monaco-editor icon indicating copy to clipboard operation
monaco-editor copied to clipboard

Type Checking in JS File allows invalid JavaScript

Open dipamsen opened this issue 3 years ago • 6 comments

monaco-editor version: Latest Browser: Chrome OS: Windows Playground code that reproduces the issue: Extending Language Services > Configuring JavaScript Defaults

(Set noSemanticValidation to false on line 8)

// Add additonal d.ts files to the JavaScript language service and change.
// Also change the default compilation options.
// The sample below shows how a class Facts is declared and introduced
// to the system and how the compiler is told to use ES6 (target=2).

// validation settings
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
	noSemanticValidation: false,
	noSyntaxValidation: false
});

// compiler options
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
	target: monaco.languages.typescript.ScriptTarget.ES6,
	allowNonTsExtensions: true
});

// extra libraries
var libSource = [
	'declare class Facts {',
	'    /**',
	'     * Returns the next fact',
	'     */',
	'    static next():string',
	'}',
].join('\n');
var libUri = 'ts:filename/facts.d.ts';
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
// When resolving definitions and references, the editor will try to use created models.
// Creating a model for the library allows "peek definition/references" commands to work with the library.
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri));

var jsCode = [
	'"use strict";',
	'',
	'class Chuck {',
	'    greet() {',
	'        return Facts.next();',
	'    }',
	'}'
].join('\n');

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

In this editor, the language is set to javascript and semantic validation is turned on for type checking. (Equivalent to // @ts-check in VSCode).

Since the compiler is TypeScript, it allows any valid TypeScript, which can be invalid JavaScript.

Take the following code block for example:

let x = 10;
x.nonExistantMethod();

let y: any = 20;

type MyType = string;

Expected Behaviour (from VSCode)

let x = 10;
x.nonExistantMethod(); // Error: Property 'nonExistantMethod' does not exist on type 'number'.

let y: any = 20; // Error: Type annotations can only be used in TypeScript files.

type MyType = string; // Error: Type aliases can only be used in TypeScript files.

Actual Behaviour (in playground)

let x = 10;
x.nonExistantMethod(); // Error: Property 'nonExistantMethod' does not exist on type 'number'.

let y: any = 20; // No Error

type MyType = string; // No Error

dipamsen avatar May 23 '21 17:05 dipamsen

I think you have to include allowJs and checkJs in the compiler options for this to work properly, otherwise it seems to fall back to TypeScript mode even if your model is JavaScript. But I agree that the experience could be improved here.

// compiler options
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES6,
    allowJs: true,
    checkJs: true,
    allowNonTsExtensions: true
});

spahnke avatar May 24 '21 07:05 spahnke

@spahnke thanks... exactly what I was looking for 👍

dipamsen avatar May 24 '21 09:05 dipamsen

@alexdima can we set this as default for js?

hediet avatar Jun 04 '21 17:06 hediet

@orta What would you recommend? Here are the JS defaults.

alexdima avatar Jun 10 '21 20:06 alexdima

I am using the following configuration:

  monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: false,
    noSyntaxValidation: false
  });
  monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES6,
    allowJs: true,
    checkJs: true,
    allowNonTsExtensions: true
  });
  monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource);

I then use JSDoc to reference the type and it works for intellisense, but if I break the type requirement then I don't see the red mark that I expect. Is it supposed to work now?

Please let me know if I should provide a playground with an example.

giacomorebonato avatar Feb 11 '22 17:02 giacomorebonato

I am using the following configuration:

  monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: false,
    noSyntaxValidation: false
  });
  monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES6,
    allowJs: true,
    checkJs: true,
    allowNonTsExtensions: true
  });
  monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource);

I then use JSDoc to reference the type and it works for intellisense, but if I break the type requirement then I don't see the red mark that I expect. Is it supposed to work now?

Please let me know if I should provide a playground with an example.

image

it's working for [email protected]

gao-sun avatar Apr 19 '24 07:04 gao-sun