Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Typescript Plugin #320

Closed
5 tasks
hzoo opened this issue Jan 22, 2017 · 14 comments
Closed
5 tasks

Typescript Plugin #320

hzoo opened this issue Jan 22, 2017 · 14 comments

Comments

@hzoo
Copy link
Member

hzoo commented Jan 22, 2017

Ref https://twitter.com/left_pad/status/820054499389804544

This would help tooling for other things like ESLint, prettier, and users that use both Babel and Typescript (and using either < stage 3 syntax or want to use Babel to compile). And maybe other things in the future?

Now I'm not sure anyone on the team is able to dedicate time to create or maintain the plugin (there's plenty of stuff to work on already and all as volunteers) but we can help out with questions (testing, how it works, etc). I think it would work the same as how we maintain the flow plugin. The Flow team submits PRs for upcoming features/fixes and we help to review the changes according to our style/codebase.

A new proposal requires a few changes: https://github.com/babel/babel/wiki/Adding-a-new-Proposal-to-Babel. Basically a change to the parser, the code generator (for consistency although maybe not necessary), the AST spec doc, the
AST helper functions, and to the plugin that removes the types.

We are determining what to do about spec changes/major bumps via #275. Basically a change that isn't a major bump would be a different plugin so we can just release a minor of the parser rather than a major bump.

The flow team is available to talk to us via slack/github and now we also have a #typescript room in our slack so can also discuss with the TS team and others that want to help out with this effort. (Signup at http://slack.babeljs.io/, the room url after you've signed in is https://babeljs.slack.com/messages/typescript/).

I'm going to edit this section later about the basics of implementing this but just wanted to get an issue started.


  • find and extend the correct hooks for TS (probably similar to flow for most, need a few new ones)
  • create all the helper parser methods pp.methodHere
  • add to plugins

    babylon/src/index.js

    Lines 14 to 17 in b6c3b5a

    import flowPlugin from "./plugins/flow";
    import jsxPlugin from "./plugins/jsx";
    plugins.flow = flowPlugin;
    plugins.jsx = jsxPlugin;
  • import tests from TS?
  • update readme
@JamesHenry
Copy link
Member

I am going to dig into this ASAP, but just wanted to note in advance that it would be great to avoid duplicating the efforts we have already made on https://github.com/eslint/typescript-eslint-parser, which is solving a very similar problem of ESTree and TS AST interop/conversion.

@xtuc
Copy link
Member

xtuc commented Jan 23, 2017

@danez is currently working on compatibility with ESTree #277

@danez
Copy link
Member

danez commented Jan 24, 2017

IMHO the best way to go for TS right now is forking babylon and there making the adjustments to parse TypeScript. Babel can then use this alternative parser and also an alternative generator (which can be based on babel-generator). Transforms in babel can live independently anyway.
It maybe even easier to adjust the TypeScript parser to have an option to output babel-compatible AST, so it can be used directly in babel, but I have never had a look at TypeScript so dunno.

I think it would be good to not add more different syntax extensions to the babel repos to keep them more maintainable, not just code-wise, but also issues and PR which would increase if we add more and more stuff (and we already have a lot). And instead focus more on making it more easy to extend.

@zerkalica
Copy link

It's possible to extract some AST subset, compatible with flow and ts? For writing some universal transformation plugins.

@JamesHenry
Copy link
Member

@danez

It maybe even easier to adjust the TypeScript parser to have an option to output babel-compatible AST

So TS + typescript-eslint-parser is already a way to effectively take TypeScript source code and produce an ESTree AST.

If I understand correctly, the work currently being done on Babel + ESTree is around Babel outputting ESTree, but if it were possible to for Babel to also consume ESTree as an option, then we potentially have a lot of the moving parts already...

I don't yet know enough about Babel to know how that relates to @hzoo task list in the description above

@danez
Copy link
Member

danez commented Jan 24, 2017

@JamesHenry Nearly.
The work that is currently done is to have an option (or plugin) that enables babylon (the parser of babel) to output estree. This is so that other tools like eslint, react-docgen, basically everything that consumes estree ASTs to be able to drop in babylon and be able to support every spec that babylon supports.

Afaik there are no plans to use the estree mode within babel, as the changes that were made to the ESTree format are all valuable additions/changes and make it way easier to write plugins in babel. IT would be nice to contribute them back to ESTree, but they don't allow/want any breaking change.

@hzoo
Copy link
Member Author

hzoo commented Jan 24, 2017

@danez

The intention of the issue/discussion earlier was that I thought we could possibly have a ts plugin like with flow/jsx? And that the Babel team wouldn't be the ones maintaining/creating it, but it would be like flow in that the Flow team can make PRs etc.

And yes @JamesHenry already has done separate work via typescript-eslint-parser which uses the TS parser -> ESTree. This issue was about getting babylon itself to parse TS but maybe that's unnecessary?

And instead focus more on making it more easy to extend.

Not sure what we can do there yet?

@danez
Copy link
Member

danez commented Jan 24, 2017

Well even with flow, we are not up2date with all the syntax-features it supports and my main concern is that for every syntax-plugin (flow, jsx, ts, ...) all the bugs would come in here in this repo, and right now it is the babel-team triaging, managing and fixing them most of the time and not the flow team (no offense her btw, probably they would do it if we ping them). But more plugins -> more bugs/changes/updates.

That is why i think it would be nice to have separate repos with separate responsibilities.

Of course making external plugins work in a reasonable way is a complete different topic and I have no idea how atm.

@stephen
Copy link

stephen commented Feb 28, 2017

I posted this in the #typescript slack channel, but this might have better visibility:

I'm curious if anyone has given thought to how to name/shape the ast extensions, i.e. should they attempt to resemble the official ts compiler? or the ts grammar spec? or potentially share node names with flow?

some notes:

  • the ts official compiler AST isn’t a 1:1 mapping to the spec grammar (as would be expected I guess)
  • some of the ts compiler nodes are directly mappable to EStree nodes (i.e. ts PropertyAccessExpression -> estree MemberExpression)
  • some of the ts compiler nodes and flow nodes are directly mappable (i.e. StringTypeAnnotation -> StringKeyword)
    • others are not, i.e. InterfaceDeclaration in the flow AST has a body property which is an ObjectType that holds the interface's indexers, properties, and call properties. In the ts compiler AST, InterfaceDeclaration directly references the indexers, properties, and call properties without the intermediate ObjectType. (The ts grammar spec otoh, does have the ObjectType concept which is analogous to the flow node by the same name.)
  • some concepts between the two are somewhat analogous, but do not have exactly the same semantics (i.e. interfaces can have mixins in flow, but there are no mixins in ts)

I suspect that a typescript extension should target a separate set of ast node names from flow to entirely avoid collisions where the two systems don't match, but that leaves a question for how to best extend beyond the base ESTree types (attempting to match the ts compiler, or attempting to match a combination of the grammar spec + flow ast node structure).

@JamesHenry
Copy link
Member

@stephen As mentioned in slack, I will document what we have done in typescript-eslint-parser. It is something we have already had to tackle

@hzoo
Copy link
Member Author

hzoo commented Jun 29, 2017

Initial pr merged in #523!

Babel prs: babel/babel#5896, babel/babel#5899, babel/babel#5856

@hzoo
Copy link
Member Author

hzoo commented Aug 8, 2017

Ok all 3 PRs are merged, and released in alpha.19

Can test with

{
  "presets": ["typescript"]
}

You'll want to make sure all your packages are 7.0.0-alpha.19, although babel-loader/gulp-babel are already out of alpha/beta since they won't need to be updated.

We have

https://github.com/babel/babel/labels/area%3A%20typescript
https://github.com/babel/babylon/issues?q=is%3Aissue+is%3Aopen+label%3Atypescript

to track issues while were in alpha/beta since this is a new feature/preset, and will probably need fixes!

@hzoo hzoo closed this as completed Aug 8, 2017
@jiayihu
Copy link

jiayihu commented Aug 8, 2017

@hzoo do you have any resource or link to get started with writing Babel plugins for TS? Or is it the same as with Flow? Anyway thank you for your great work!! 😍

@nicolo-ribaudo
Copy link
Member

It works like with Flow, but with different nodes. You can find them in the TypeScript sections of src/types.js:
https://github.com/babel/babylon/blob/master/src/types.js#L792
https://github.com/babel/babylon/blob/master/src/types.js#L869

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants