Transpile TypeScript code to JavaScript with Closure annotations.
—
The type translation system converts TypeScript type annotations into Closure Compiler-compatible JSDoc type expressions, enabling full type information preservation through the compilation process.
Core class responsible for translating TypeScript types to Closure Compiler format.
/**
* Translates TypeScript types to Closure Compiler types
*/
class TypeTranslator {
/** Whether translation is for externs */
readonly isForExterns: boolean;
constructor(
host: AnnotatorHost,
typeChecker: ts.TypeChecker,
node: ts.Node,
pathUnknownSymbolsSet: Set<string>,
symbolsToAliasedNames: Map<ts.Symbol, string>,
symbolToNameCache: Map<ts.Symbol, string>,
ensureSymbolDeclared?: (sym: ts.Symbol) => void
);
/** Converts symbol to string representation */
symbolToString(sym: ts.Symbol): string | undefined;
/** Translates type to Closure format */
translate(type: ts.Type): string;
/** Checks if symbol is always unknown */
isAlwaysUnknownSymbol(symbol: ts.Symbol): boolean;
/** Marks type parameter as unknown */
markTypeParameterAsUnknown(symbol: ts.Symbol): void;
}Usage Example:
import { TypeTranslator } from "tsickle";
const translator = new TypeTranslator(host, typeChecker, node);
const closureType = translator.translate(tsType);
// Result: "!Array<string>" for TypeScript "string[]"Specialized translator for handling types within module scope, managing import aliases and dependencies.
/**
* Translates types within module scope for JSDoc generation
*/
class ModuleTypeTranslator {
readonly symbolsToAliasedNames: Map<ts.Symbol, string>;
readonly sourceFile: ts.SourceFile;
readonly typeChecker: ts.TypeChecker;
constructor(
sourceFile: ts.SourceFile,
typeChecker: ts.TypeChecker,
host: AnnotatorHost,
diagnostics: ts.Diagnostic[],
isForExterns: boolean
);
/** Converts type to Closure format */
typeToClosure(context: ts.Node, type?: ts.Type): string;
/** Creates new type translator */
newTypeTranslator(context: ts.Node): TypeTranslator;
/** Checks if symbol is unknown */
isAlwaysUnknownSymbol(symbol: ts.Symbol): boolean;
/** Requires and translates type */
requireType(context: ts.Node, type: ts.Type): string;
}Utility functions for validating and checking type properties.
/**
* Validates Closure property names
*/
function isValidClosurePropertyName(name: string): boolean;
/**
* Checks if symbol is declared in builtin lib.d.ts
*/
function isDeclaredInBuiltinLibDTS(node: ts.Node): boolean;
/**
* Checks if type/value conflict is handled
*/
function typeValueConflictHandled(sym: ts.Symbol): boolean;
/**
* Checks if symbol is always unknown
*/
function isAlwaysUnknownSymbol(pathSet: Set<string>, symbol: ts.Symbol): boolean;
/**
* Extracts rest parameter type
*/
function restParameterType(typeChecker: ts.TypeChecker, type: ts.Type): ts.Type | undefined;Functions for debugging type translation issues.
/**
* Converts type to debug string
*/
function typeToDebugString(type: ts.Type): string;
/**
* Converts symbol to debug string
*/
function symbolToDebugString(sym: ts.Symbol): string;// TypeScript -> Closure
string -> string
number -> number
boolean -> boolean
void -> void
null -> null
undefined -> undefined
any -> ?
unknown -> ?// Arrays
string[] -> !Array<string>
Array<number> -> !Array<number>
ReadonlyArray<T> -> !Array<T>
// Objects
{x: number} -> {x: number}
Record<string, T> -> !Object<string, T>
// Functions
(x: string) => number -> function(string): number
(...args: string[]) => T -> function(...string): T
// Unions
string | number -> (string|number)
T | null -> ?T
T | undefined -> (T|undefined)
// Generics
Promise<T> -> !Promise<T>
Map<K, V> -> !Map<K, V>// Optional parameters
(x?: string) => void -> function(string=): void
// Rest parameters
(...items: T[]) => void -> function(...T): void
// Type assertions preserved in specific contexts
value as Type -> /** @type {Type} */ (value)The type translator behavior can be configured through the AnnotatorHost:
interface AnnotatorHost {
/** Whether to generate untyped output */
untyped?: boolean;
/** Paths to exclude from type transformation */
typeBlackListPaths?: Set<string>;
/** Paths with unknown types */
unknownTypesPaths?: Set<string>;
/** Enable automatic property quoting */
enableAutoQuoting?: boolean;
}Configuration Example:
const host: AnnotatorHost = {
pathToModuleName: (context, importPath) => importPath,
untyped: false, // Generate full type annotations
typeBlackListPaths: new Set(['/node_modules/']), // Skip type checking for node_modules
unknownTypesPaths: new Set(['/legacy/']), // Treat legacy code as unknown types
enableAutoQuoting: true // Automatically quote invalid property names
};Helper class for managing JSDoc comments during type translation.
/**
* Encapsulates mutable JSDoc comment
*/
class MutableJSDoc {
constructor(node: ts.Node, sourceComment: ts.SynthesizedComment | null, tags: Tag[]);
/** Updates comment, optionally escaping extra tags */
updateComment(escapeExtraTags?: Set<string>): void;
}Type translation integrates directly with JSDoc generation, automatically inserting proper type annotations:
// Before transformation (TypeScript)
function processUser(user: User): Promise<ProcessedUser> {
return Promise.resolve(transformUser(user));
}
// After transformation (with JSDoc)
/**
* @param {!User} user
* @return {!Promise<!ProcessedUser>}
*/
function processUser(user) {
return Promise.resolve(transformUser(user));
}Install with Tessl CLI
npx tessl i tessl/npm-tsickle