What is tsickle?
Tsickle is a TypeScript to Closure Compiler transformer that helps in generating Closure-compatible JavaScript from TypeScript code. It is primarily used to bridge the gap between TypeScript and Google's Closure Compiler, enabling advanced optimizations and type-checking.
What are tsickle's main functionalities?
Type Annotations to JSDoc
Tsickle converts TypeScript type annotations into JSDoc comments, which can be understood by the Closure Compiler for type-checking and optimizations.
/* TypeScript Code */
function add(a: number, b: number): number {
return a + b;
}
/* Transformed JavaScript Code */
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
function add(a, b) {
return a + b;
}
Closure Compiler Compatibility
Tsickle transforms TypeScript classes and other constructs into a form that is compatible with the Closure Compiler, enabling advanced optimizations.
/* TypeScript Code */
class Example {
private value: string;
constructor(value: string) {
this.value = value;
}
}
/* Transformed JavaScript Code */
/**
* @constructor
* @param {string} value
*/
var Example = function(value) {
/** @private {string} */
this.value = value;
};
Type Checking with Closure Compiler
By converting TypeScript types to JSDoc, Tsickle allows the Closure Compiler to perform type-checking on the generated JavaScript code.
/* TypeScript Code */
function greet(name: string): string {
return 'Hello, ' + name;
}
/* Transformed JavaScript Code */
/**
* @param {string} name
* @return {string}
*/
function greet(name) {
return 'Hello, ' + name;
}
Other packages similar to tsickle
babel
Babel is a JavaScript compiler that allows you to use next-generation JavaScript, today. It can transform TypeScript code into JavaScript, but it does not provide the same level of integration with the Closure Compiler as Tsickle.
typescript
The TypeScript compiler (tsc) itself can compile TypeScript to JavaScript. While it does not specifically target Closure Compiler compatibility, it is a robust and widely-used tool for TypeScript development.
google-closure-compiler
Google Closure Compiler is a tool for making JavaScript download and run faster. While it can be used in conjunction with Tsickle, it does not itself transform TypeScript code.
Tsickle - TypeScript to Closure Translator
Tsickle converts TypeScript code into a form acceptable to the Closure
Compiler. This allows using TypeScript to transpile your sources, and then
using Closure Compiler to bundle and optimize them, while taking advantage of
type information in Closure Compiler.
What conversion means
A (non-exhaustive) list of the sorts of transformations Tsickle applies:
- inserts Closure-compatible JSDoc annotations on functions/classes/etc
- converts ES6 modules into
goog.module
modules - generates externs.js from TypeScript d.ts (and
declare
, see below) - declares types for class member variables
- translates
export * from ...
into a form Closure accepts - converts TypeScript enums into a form Closure accepts
- reprocesses all jsdoc to strip Closure-invalid tags
In general the goal is that you write valid TypeScript and Tsickle handles
making it valid Closure Compiler code.
Warning: work in progress
We already use tsickle within Google to minify our apps (including those using
Angular), but we have less experience using tsickle with the various JavaScript
builds that are seen outside of Google.
We would like to make tsickle usable for everyone but right now if you'd like
to try it you should expect to spend some time debugging and reporting bugs.
Installation
- Execute
npm i
to install the dependencies.
Usage
Project Setup
Tsickle works by wrapping tsc
. To use it, you must set up your project such
that it builds correctly when you run tsc
from the command line, by
configuring the settings in tsconfig.json
.
If you have complicated tsc command lines and flags in a build file (like a
gulpfile etc.) Tsickle won't know about it. Another reason it's nice to put
everything in tsconfig.json
is so your editor inherits all these settings as
well.
Invocation
Run tsickle --help
for the full syntax, but basically you provide any tsickle
specific options and use it as a TypeScript compiler.
Differences from TypeScript
Closure and TypeScript are not identical. Tsickle hides most of the
differences, but users must still be aware of some differences.
declare
Any declaration in a .d.ts
file, as well as any declaration tagged with
declare ...
, is intepreted by Tsickle as a name that should be preserved
through Closure compilation (i.e. not renamed into something shorter). Use it
any time the specific string names of your fields are significant. That would
most often happen when the object either coming from outside your program, or
being passed out of the program.
Example:
declare interface JSONResult {
username: string;
}
let r = JSON.parse(input) as JSONResult;
console.log(r.username);
By adding declare
to the interface (or if it were in a .d.ts
file), Tsickle
will inform Closure that it must use exactly the field name .username
(and not
e.g. .a
) in the output JS. This matters for this example because the input
JSON probably uses the string 'username'
and not whatever name Closure would
invent for it. (Note: declare
on an interface has no additional meaning in
pure TypeScript.)
Exporting decorators
An exporting decorator is a decorator that has @ExportDecoratedItems
in its
JSDoc.
The names of elements that have an exporting decorator are preserved through
the Closure compilation process by applying an @export
tag to them.
Example:
/** @ExportDecoratedItems */
function myDecorator() {
// ...
}
@myDecorator()
class DoNotRenameThisClass { ... }
Development
Gulp tasks
gulp watch
executes the unit tests in watch mode (use gulp test.unit
for a
single run),gulp test.e2e
executes the e2e tests,guld test.golden
executes the golden tests,gulp test.check-format
checks the source code formatting using
clang-format
,gulp test
runs unit tests, e2e tests and checks the source code formatting.
Environment variables
Export the environment variable UPDATE_GOLDENS=1
to have the test suite
rewrite the golden files when you run it.
Export the environment variable TEST_FILTER
, a regex, to limit the end-to-end
tests (found in test_files/...
) run tests with a name matching the regex.