sublimelsp / LSP-typescript

TypeScript, JavaScript support for Sublime LSP plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using Flow in React Project. Type annotations can only be used in TypeScript files error.

bigkrp opened this issue · comments

In my react\javascript project i use Flow, and often get this error:
error Type annotations can only be used in TypeScript files. ​typescript:8010

How can i disable it?

LSP: Disable Language Server in Project -> LSP-typescript

You don't want to run LSP-typescript in a flow project. You might want to use LSP-flow instead.

We have a huge project that has both Flow (older code) and TS (newer code), and I'd prefer to keep LSP-typescript enabled for vanilla JS. Does ST's API maybe have a way of finding out if the current file contains a certain scope? And if it does, and a file contains meta.flow-type.js, as marked by JS Custom, then disable the server for it?

Is the root scope different in the flow syntax you are using? For plain javascript syntax it's source.js.

If the root syntax is different then we (or you) could do something about it. Otherwise probably not as checking for existence of some sub-scopes in the scopes is a bit too much IMO.

I don't think that's possible. JS Custom can be told to set a custom root scope, by the looks of it, but then all JavaScript files, even the ones not covered by Flow, would be marked as scope.js.flow or something. Is, perhaps, looking at the first line of the file an option? FlowType requires a // @flow at the beginning of each type-checked file, an easy discriminator.

It's a problem that both plain JS and flow use the same syntax since the syntax (or its root scope) is currently the way to map language servers to files that they run on.

The only solution I can think of is to:

  • use bundled Javascript syntax for *.js files by default
  • make your JSCustom syntax not apply to *.js files by default
  • use https://packagecontrol.io/packages/ApplySyntax to assign the flow syntax to flow files by checking the first line for // @flow.

A .sublime-syntax can have a first_line_match too. That would alleviate the need for ApplySyntax. However, I don’t know whether JSCustom can be configured in such a way to add a first_line_match (and no extensions) for a generated syntax. Maybe @Thom1729 can shed a light on this?

Good idea. I've added a first_line_match option to JS Custom and you can try it out in v4.2.0-beta.5.

Wow, that's great, thank you! However, looking at ST's docs, first_line_match comes into play only when a file is opened without a recognized extension. That wouldn't work for .js files, no?

Hmm, evidently not. It looks like it might be a job for ApplySyntax after all.

Out of curiosity, how do you/how does your build system differentiate between the Flow and TS files?

No problem! I couldn't get ApplySyntax to work, but will try some more.

The project is transpiled by Babel, all types are just stripped away. Static analysis is separate, Flow runs only on files with // @flow in them, and TS runs only on .tsx? files. And then TS's language server can be useful on plain JavaScript files too.

I've configured ApplySyntax + JS Custom so that they set the scope to scope.js.flow, but LSP-typescript still picks up the file. Do I need to change something in its config? I thought since both the syntax name and the scope are different from the default config, it would work as-is?

For future readers, my JS Custom config:

{
  "configurations": {
    "Flow": {
      "scope": "source.js.flow",
      "flow_types": true,
      "jsx": true
    }
  }
}

And my ApplySyntax config:

{
  "syntaxes": [
    {
      "syntax": "User/JS Custom/Syntaxes/Flow",
      "match": "all",
      "rules": [{ "file_path": ".*\\.jsx?$" }, { "first_line": "^// @flow" }]
    }
  ]
}

In LSP-typescript.sublime-settings try:

    "selector": "source.js -source.js.flow",

selector is the ST4-only configuration option that has more flexibility than the legacy languages one.

If that works then you can potentially extend it with source.ts and other if you want.

If you set the scope in the JSCustom config to something like source.flow, is LSP-typescript still attached?

@rwols that would probably work but would likely break a lot of things (packages, snippets) that depend on source.js scope.

I see. Maybe we need an exact match instead of a selector match. Or exclude this source.js.flow scope in language-ids.sublime-settings.

This is excellent, thank you everybody! Should I document the ApplySyntax + JS Custom part in the readme?