Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-63600

Investigate support for TypeScript in QML

    XMLWordPrintable

Details

    Description

      To make development of large scale QML applications with many .qml and .js files easier, we could investigate the idea of supporting TypeScript.

      There are two areas that need to be changed in order for us to claim TypeScript support:

      1. The ability to edit .qml and .ts files in Qt Creator with code completion support and all the other IDE features the TS language services provide.
      2. The ability to use TypeScript syntax and features in .qml as well as the ability to import .ts files with the import statement.

      TypeScript is a command line tool, but it also supports the language server protocol and (most importantly) it provides an API to interact with. That API allows for individual script transformations, incremental editing, code completion and many more features.

      We do not want to re-implement the entire language, the built-in IDE support or the compiler itself. Instead we should attempt to re-use the original implementation, with modifications. In order for the QML engine to be able to load .ts files or use TS syntax in .qml files, we need the TS compiler to transform TS to ES5 syntax, so that our built-in ES5 engine can run the code. In order to be able to take advantage of the TS IDE integration in Qt Creator, we need to implement the language service host interface and run the TS "library" in QJSEngine inside Qt Creator.

      With regards to supporting QML syntax, we can consider two different approaches:

      1. Extract script bindings from the QML AST and feed them separately into the TS compiler. That could be done either by feeding the bindings as strings (similar to how we used to use V8) or by using a synthetic AST.
      2. Modify the TS AST to support the QML grammar and extend the C++ parser to parse the entire TS syntax. We may want to consider sharing the AST at run-time, which would require light-weight V4 bindings. If we choose not to share the AST, then we need to extend the hand-written TS parser to also support parsing QML and we'll parse every qml file at least twice. On the other hand the incremental editing support in TS at the moment appears to only work on a textual level, but perhaps it can be changed to also support incremental changes on an AST level.

      From a development point of view, the use of TS requires a real compile step at development time, as we do not want to run the entire TS compiler at run-time when loading .qml files. Consequently we'd want to always compile .qml/.js/.ts files ahead of time to bytecode (or generally speaking our cache files) and only load those at run-time.

      As a break-down I would suggest two parallel initial steps:

      1. Prototype integrating the TS compiler in Qt Creator by implementing the language services host interface and running the TS compiler inside QJSEngine. There was once a prototype that demonstrated that this is possible, but it will have to be re-done. This boils down to including a JS build of the TS compiler, feeding it into QJSEngine inside a new creator text editor plugin, implementing the language services host interface and this way build the bridge between the text editor and the TS compiler that is run interactively. This would not require any grammar changes if we stick to just editing of .ts files at first.
      2. Add the QML grammar to the C++ and TS AST and implement AST bindings. This could be a little CLI tool at first that takes a .qml file, parses it in C++, exposes it to TS via V4 bindings and then uses the TS API to emit the AST into textual form again, and by the way of doing run the TS compiler that performs type checking and produces diagnostics.

      Finally we'd want to use TS to transform the AST that contains TS elements to an AST that is solely ES5 compliant, so that we can feed that into the V4 codegen to generate bytecode. That could be implemented in the qmlcachegen tool.

      Update:

      Another fruitful discussion around this topic with Lars and Frederik revealed that we may be able to achieve the primary goal - making large scale development easier through a better type system - without integrating the entire TS engine. Instead we could add type annotations to QML files where missing (to function parameters for example) and simply do strict type checking inside expressions during assignments at v4 codegen time. This will also require a cast operator. But overall it may not be such a crazy amount of work. It's also important to be able to enable this on a per-file basis and later per project.

      Attachments

        Issue Links

          Activity

            People

              shausman Simon Hausmann
              shausman Simon Hausmann
              Votes:
              10 Vote for this issue
              Watchers:
              23 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: