{"id":22793270,"url":"https://github.com/fivetran/typescript-closure-tools","last_synced_at":"2025-10-27T00:44:30.040Z","repository":{"id":16747633,"uuid":"19505196","full_name":"fivetran/typescript-closure-tools","owner":"fivetran","description":null,"archived":false,"fork":false,"pushed_at":"2018-11-02T06:27:40.000Z","size":6018,"stargazers_count":63,"open_issues_count":2,"forks_count":11,"subscribers_count":85,"default_branch":"master","last_synced_at":"2025-03-29T05:33:48.674Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fivetran.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-06T18:13:10.000Z","updated_at":"2025-02-24T15:12:06.000Z","dependencies_parsed_at":"2022-09-26T21:01:47.998Z","dependency_job_id":null,"html_url":"https://github.com/fivetran/typescript-closure-tools","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Ftypescript-closure-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Ftypescript-closure-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Ftypescript-closure-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Ftypescript-closure-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fivetran","download_url":"https://codeload.github.com/fivetran/typescript-closure-tools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625554,"owners_count":21135517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-12T03:18:58.059Z","updated_at":"2025-10-27T00:44:24.993Z","avatar_url":"https://github.com/fivetran.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Use it online](http://fivetran.github.io/typescript-closure-tools)\n\nConverts [Closure-style JSDoc type annotations](https://developers.google.com/closure/compiler/docs/js-for-compiler)\nto [TypeScript definition files](http://www.typescriptlang.org/Handbook#writing-dts-files).\n\nThe purpose of this tool is to assist developers writing TypeScript definitions on large libraries.\nOur goal is to generate correct type definitions in most cases, and to provide a useful starting\npoint for manually fixing the difficult cases.\n\n# Setup\n\n```bash\ngit clone git@github.com:fivetran/typescript-closure-tools.git\ncd typescript-closure-tools\ngit submodule update --init\nnpm install\nnode definition-generator/src/main.js test/class.js class.d.ts # Run a single example\nsudo npm install -g \n```\n\n# Usage\n\n```\nclosure2ts\n  [--provides symbols.tsv]\n  [--globals output/dir/global-declarations.d.ts]\n  [--input_root input/dir]\n  [--output_root output/dir]\n  [--include_private boolean]\n  input/dir/input-file.js output/dir/output-file.d.ts\n  input/dir/another-input-file.js output/dir/another-output-file.d.ts\n  ...\n```\n\n* `--provides symbols.tsv` A tab-separated file where each row has the form `file-name.js    providedSymbol`\nIf this option isn't present, we will simply look for global symbols in the input files.\n* `--globals output/dir/global-declarations.d.ts` A TypeScript declaration that will be referenced at the top of every output file.\n* `--input_root input/dir` Root of inputs, considered when computing relative paths for `///\u003creference path=\"...\" /\u003e` tags.\n* `--output_root output/dir` Root of outputs, considered when computing relative paths for `///\u003creference path=\"...\" /\u003e` tags.\n* `--include_private boolean` Whether to include items marked as private (@private), defaults to false.\n\n# Structure\n\n* `index/` Typescript definition files for the Closure library\n\n## definitions-generator/\n\n* `src/` Typescript sources\n* `scripts/` Shell scripts used for converting the Closure library\n* `test/` Jasmine specs and example JS files used in testing\n* `lib/` Dependencies\n\n# Running the tests\n\n```bash\n./scripts/test.sh\n```\n\n# Differences between the Closure type system and TypeScript\n\nThere are several important differences between the Closure type system and TypeScript.\n\n## Differences that are resolved automatically\n\n### Static inheritance\n\nIn typescript, static properties of classes are inherited:\n\n```typescript\ndeclare class SuperClass { }\ndeclare module SuperClass {\n    var myStaticProperty: number;\n}\n\ndeclare class SubClass extends SuperClass { }\n\nSubClass.myStaticProperty; // : number\n```\n\nIn Closure they are not:\n```javascript\n/** @constructor */\nSuperClass = function() { };\n/** @type {string} */\nSuperClass.myStaticProperty;\n/** @type {string} */\nSuperClass.prototype.myInstanceProperty;\n\n/** @extends {SuperClass} */\nSubClass = function() { };\ngoog.inherits(SubClass, SuperClass);\n\nSubClass.myStaticProperty; // undefined\n```\n\nTo fix this, we create a common superclass without the static properties:\n\n```typescript\ndeclare class SuperClass extends SuperClass__Class { }\ndeclare module SuperClass {\n    class __Class {  // fake common superclass without myStaticProperty\n        myInstanceProperty: string;\n    }\n    myStaticProperty: string; // static property that won't be inherited by 'extends SuperClass__Class'\n}\n\ndeclare class SubClass extends SubClass__Class { }\ndeclare module SubClass {\n    class __Class extends SuperClass__Class { }\n}\n```\n\nThese fake superclasses don't actually exist and are present solely to simulate the behavior of\n`goog.inherits(SubClass, SuperClass)` in TypeScript definition files.\nCalling `new SuperClass__Class` or `extends SuperClass__Class` in non-declaration TypeScript code\nwill generate a runtime error.\nYou should use `new SuperClass` and `extends SuperClass` in non-declaration TypeScript code.\n\n### Private types\n\nIn Closure, the `@private` annotation is not enforced, and private type definitions, interfaces, classes and enums are\noften used in public function declarations. Therefore, these private types are included in the TypeScript definition.\n\n## Differences that must be fixed manually\n\n### Shadowing\n\nIn typescript, the current module shadows the global namespace:\n\n```typescript\ndeclare class MyClass;\ndeclare module myModule {\n    class MyClass;\n    var myValue : MyClass; // Refers to myModule.MyClass, not global MyClass\n```\n\nThis can create problems when referring to global variables that are shadowed by locals:\n\n```javascript\ngoog.Error = function() { }\n\n/**\n * @param {Error} e\n */\ngoog.f = function(e) { };\n```\n\nbecomes:\n\n```typescript\ndeclare module goog {\n    class Error { }\n\n    function f(e: Error) { }\n}\n```\n\n# RequireJS support\n\nBasic RequireJS support is present:\n\n```javascript\ndefine(function(require, exports, module) {\n    /** @param {number} x */\n    function functionDeclaration(x) { }\n});\n```\n\nbecomes:\n\n```typescript\nmodule MODULE {\n    functionDeclaration(x: number): void;\n}\n```\n\n## Limitations\n\n### Declarations are always placed in a module named `MODULE`\n\n### Only symbols with JSDoc annotations are exported\n\n```javascript\ndefine(function(require, exports, module) {\n    /** @type {number} */\n    var documentedSymbol = 1;\n\n    var ignoredSymbol = 2;\n\n    exports.documentedSymbol = documentedSymbol;\n    exports.ignoredSymbol = 2;\n});\n```\n\nbecomes:\n\n```typescript\nmodule MODULE {\n    var documentedSymbol: number;\n}\n```\n\n### `exports` and `module` are ignored\n\nSymbols are exported using their local name:\n\n```javascript\ndefine(function(require, exports, module) {\n    /** @type {number} */\n    var localName = 1;\n\n    exports.exportedName = localName;\n});\n```\n\nbecomes:\n\n```typescript\nmodule MODULE {\n    var localName: number;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivetran%2Ftypescript-closure-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffivetran%2Ftypescript-closure-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivetran%2Ftypescript-closure-tools/lists"}