New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicit function scope #2147
Comments
Duplicate of #1661 |
At least for the return statement, you can use the code sample mentioned in microsoft/monaco-typescript#46 to ignore that specific diagnostic. |
@alexdima I get this issue was closed, but I think #1661 is too broad of a fix and not really a duplicate of this. I was thinking more of something like a DiagnosticsOptions flag like @spahnke Thanks. The same principle could be used to disable 2451 as well. |
You can work around that pretty easily by only including necessary types in your extra lib instead of the actual code you wrap the user's code in. Consider the following function with parameters and a predefined global object function implicitFunction(a: number, b: number) {
// user code goes here
return a + b + foo.bar();
} Then you want your users to just write return a + b + foo.bar(); into the editor and get completion for everything, as far as I understand. The interface Foo {
bar(): number;
}
// global object
declare const foo: Foo;
// parameters - declare as var if you want the user to be able to change these, otherwise use const
declare var a: number;
declare var b: number; This is how we use the editor for this exact use case. Provide the necessary types by a Does this help you? Full playground example adopted from https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-javascript-defaults: // validation settings
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
noSuggestionDiagnostics: false,
diagnosticCodesToIgnore: [1108],
});
// compiler options
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.ES6,
allowNonTsExtensions: true
});
// extra libraries
const libSource = `
interface Foo {
bar(): number;
}
// global object
declare const foo: Foo;
// parameters
declare var a: number;
declare var b: number;
`
const 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));
const jsCode = `return a + b + foo.bar();`
monaco.editor.create(document.getElementById('container'), {
value: jsCode,
language: 'javascript'
}); |
Thank you for your reply. Sadly, it does not address the original problem, though. If you type Surpressing the 2451 error in addition to 1108 seems like the only viable workaround for now: monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
noSuggestionDiagnostics: false,
diagnosticCodesToIgnore: [1108, 2451],
}); |
Of course I can only speak for our application, but if we declare a global variable we would never ever want the user to be able to overwrite those; even in a function scope. Because that only leads to subtle bugs I don't want to hunt down 😄 So the questions that you need to answer for yourself are: If the global variable is essential and should be used inside the function, do you really want the user to overwrite that; even temporarily? And, if it's not used by your users inside your function, do you need to declare it in the first place? If you really want to have both, then you're right TypeScript is a bit too strict for your needs. And even an option like But also consider that you probably will need to debug the following code for a user at some point in the future if you just suppress the error or use // ... 20 lines of code
var foo = "asdf"; // sneaky redeclaration
// ... another 50 lines of code
return foo.bar(); // this will not work now Or even worse they write the code let test = 1;
// ... other code
let test = 2; and now the editor says everything is fine, but the script crashes at runtime because now they're actually redeclaring block scoped variables which is not allowed. I myself would always go for the stricter error checking, or just don't declare |
You're right that it sounds a bit strange. To explain my use case a bit more, users of our application can create all kinds of identifiers through a web UI that translate in code to classes/constants/functions. A user had one of those classes named You could say that they shouldn't use the name 'result' as a class, but it's how they happened to compose their model. 🤷♂️ Anyway, thanks again for the tips! |
This is slightly related to #953 - the difference is I would like some code to not be visible at all. I am aware of
addExtraLib
and use that to inject some custom global functions and classes for IntelliSense purposes.The use case I have is that I want a user to write a function's body only (the function declaration is not part of the model). This works fine until, for instance, the user writes something like:
If
varName
is already declared somewhere with theaddExtraLib
call, this will give a "Cannot redeclare block-scoped variable 'varName'.(2451)" error. (This won't be the case during the actual execution, but there's no way to tell monaco that!)It's also impossible to have a
return
statement, as that will cause an "A 'return' statement can only be used within a function body. (1108)" error.I would like the code to be validated as though it is in its own function scope, as is the case within a function, so this error is no longer reported.
The text was updated successfully, but these errors were encountered: