Typescript: Ability to emit TypeScript from syntax tree

Created on 8 Sep 2016  路  16Comments  路  Source: microsoft/TypeScript

Now that #5595 has landed, it has me excited that it may soon be possible to emit TypeScript. Is it now possible with the 2.1 nightly? If not, please consider this a feature request. It would open the door for a lot of cool code generation.

Related issues:

  • 2015-01-08 #1514 Building a TypeScript Syntax Tree with source from another language (F#)
  • 2015-04-20 #1651 How do you do a straight TS emit?
  • 2016-02-22 #3241 TypeScript code generation from the Language Service
API Suggestion

Most helpful comment

@alexarg As far as I know it will be in TypeScript 2.3 and is available from the nightly builds. Generally you can use the printer to generate TypeScript code from a SourceFile, a bundle of source files or a single Node.

This is a very basic example on how to transform TypeScript code and generate TypeScript again after that. I've typed everything, just that it's easier to follow what's going on.

const source: string = `function logString(param: string): void {
  console.log(param);
}`;

const sourceFile: ts.SourceFile = ts.createSourceFile(
  'test.ts', source, ts.ScriptTarget.ES2015, true, ts.ScriptKind.TS
);

// Options may be passed to transform
const result: ts.TransformationResult<ts.SourceFile> = ts.transform(
  sourceFile, [ yourTransformer ]
);

const transformedSourceFile: ts.SourceFile = result.transformed[0];

// Options may be passed to createPrinter
const printer: ts.Printer = ts.createPrinter();

const generated: string = printer.printFile(transformedSourceFile);

result.dispose();

Probably you may also want to check https://github.com/Microsoft/TypeScript/pull/13940 where you can find some more examples and explanations.

All 16 comments

Depending on what you're doing, https://github.com/RyanCavanaugh/dts-dom may be a useful alternative

@ctaggart hey there, you seem to have a pretty good grasp on the whole emitting functionality. I was just curious if you could tell me what exactly I need to watch out for in order to be able to read a .ts file, parse it, add some nodes and emit it to a new .ts file. Thanks :)

(background: I would love to be able to build the TypeScript version of my Babel plugin https://github.com/stephanos/babel-plugin-immutable-record)

@stephanos, it has been possible to do everything you are asking by using the compiler api for a while, except emit the .ts file. If it is indeed possible now, I don't know how to do it. I too would like it to be possible, which is why I opened this issue. I recommend adding a 馃憤 above if you would like to see support added.

@ctaggart thanks for your reply :) I'm now focusing on emitting .js until this issue is resolved. I managed to get started on this today and got as far as parsing the .ts and navigating through the AST nodes. But now I'm stuck: How do I create a new node (e.g. a variable declaration) and add it to an array of statements? I'd appreciate if you could share any insights or point me in the right direction. Thank you. (sorry for hijacking this issue :-/ - should I post this somewhere else?)

Would you accept a pull request on this? I'd propose a new function emit(file: SourceFile, transformers: Transformer[] = nullTransformers, newLine = "\n"): string in emitter.ts and exposing the functions in factory.ts. Since factory.ts contains a lot of helpers, I guess that should be placed in a namespace like ts.factory (instead of exposing it under ts).

I played a bit with it, and I created PR #11561.

We really need something like babel-types & babel-generator

Sometimes, we need to generate code by specs like json-schema, swagger.

There is a cool tool TSTypeInfo to do this.

However, Hope typescript could provide these features.

Now that TypeScript 2.1 has been released where ya'll are now rewriting the emit pipeline to use tree transforms, is this something that may be enabled soon. I brought up this issue at both @DanielRosenwasser's presentation and a Q&A with @ahejlsberg at the Microsoft MVP conference in November.

thanks,
Squeaky Wheel

Hey @ctaggart! #11561 was the most recent PR regarding this, but we want to do some cleanup on the API. See @mhegazy's comment at https://github.com/Microsoft/TypeScript/pull/11561#issuecomment-260215001.

TL;DR: pretty-printing a synthesized tree is planned for the 2.2 timeframe.

Now that https://github.com/Microsoft/TypeScript/pull/13940 has been merged to master, this may actually be possible now, right? @rbuckton

Yes, and it'll be in the nightlies in about an hour or two! 馃帀

Caveat: Forgive me for my last comment, as it's now slated for TypeScript 2.3.

There is still some stuff you can still use in 2.2 - having spoken with @rbuckton earlier tonight, if I'm not mistaken, the factory (#13825) and printer (#13761) will be in 2.2... which I think you should actually be all you need! So let us know how that works out. 馃槃

Great progress. I love TypeScript and community!
Is there minimal example of emitting TypeScript after transformations?

Based on the comments it seems like generating TypeScript code with TypeScript 2.2 is _to some extent_ possible? If so, could you please share some tips on how to do that?

@alexarg As far as I know it will be in TypeScript 2.3 and is available from the nightly builds. Generally you can use the printer to generate TypeScript code from a SourceFile, a bundle of source files or a single Node.

This is a very basic example on how to transform TypeScript code and generate TypeScript again after that. I've typed everything, just that it's easier to follow what's going on.

const source: string = `function logString(param: string): void {
  console.log(param);
}`;

const sourceFile: ts.SourceFile = ts.createSourceFile(
  'test.ts', source, ts.ScriptTarget.ES2015, true, ts.ScriptKind.TS
);

// Options may be passed to transform
const result: ts.TransformationResult<ts.SourceFile> = ts.transform(
  sourceFile, [ yourTransformer ]
);

const transformedSourceFile: ts.SourceFile = result.transformed[0];

// Options may be passed to createPrinter
const printer: ts.Printer = ts.createPrinter();

const generated: string = printer.printFile(transformedSourceFile);

result.dispose();

Probably you may also want to check https://github.com/Microsoft/TypeScript/pull/13940 where you can find some more examples and explanations.

I used this technique to make a transformer module:
https://github.com/lyft/react-javascript-to-typescript-transform

This is fixed now. Before we mark this closed, which version shipped with Creating and Printing a TypeScript AST working? Was it 2.4? @fabiandev comment above shows it was 2.3.

Was this page helpful?
0 / 5 - 0 ratings