├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .gitmodules ├── .travis.yml ├── @types ├── @teppeis │ └── doctrine │ │ └── index.d.ts ├── esprima │ └── index.d.ts ├── espurify │ └── index.d.ts └── estraverse │ └── index.d.ts ├── README.md ├── bin ├── check-error.sh ├── closurets.js ├── generate-alldts.sh └── generate.sh ├── builtin.d.ts ├── examples └── closure-library │ └── closure │ └── goog │ ├── array │ ├── array.d.ts │ └── array.js │ ├── base.d.ts │ ├── base.js │ ├── dom │ ├── dom.d.ts │ ├── dom.js │ ├── tagname.d.ts │ └── tagname.js │ ├── math │ ├── coordinate.d.ts │ ├── coordinate.js │ ├── math.d.ts │ ├── math.js │ ├── size.d.ts │ └── size.js │ └── string │ ├── string.d.ts │ └── string.js ├── index.js ├── index.ts ├── misc ├── error.log ├── goog.module.get.txt ├── goog.module.txt ├── goog.scope.txt └── ignore.txt ├── package-lock.json ├── package.json ├── src ├── cli.ts ├── generator.ts ├── printer.ts ├── types.ts └── util.ts ├── test ├── all.ts ├── fixtures │ ├── any.d.ts │ ├── any.js │ ├── assignment-conditional-expression.d.ts │ ├── assignment-conditional-expression.js │ ├── builtin-eventtarget.d.ts │ ├── builtin-eventtarget.js │ ├── class-constructor.d.ts │ ├── class-constructor.js │ ├── class-empty-override.d.ts │ ├── class-empty-override.js │ ├── class-extends-implements.d.ts │ ├── class-extends-implements.js │ ├── class-extends.d.ts │ ├── class-extends.js │ ├── class-inner.d.ts │ ├── class-inner.js │ ├── class-method-static.d.ts │ ├── class-method-static.js │ ├── class-method.d.ts │ ├── class-method.js │ ├── class-private.d.ts │ ├── class-private.js │ ├── class-property-static.d.ts │ ├── class-property-static.js │ ├── class-property.d.ts │ ├── class-property.js │ ├── enum-copy.d.ts │ ├── enum-copy.js │ ├── enum-literal.d.ts │ ├── enum-literal.js │ ├── enum-private.d.ts │ ├── enum-private.js │ ├── enum.d.ts │ ├── enum.js │ ├── expression-statement.d.ts │ ├── expression-statement.js │ ├── function-type.d.ts │ ├── function-type.js │ ├── functiondeclaration.d.ts │ ├── functiondeclaration.js │ ├── functions.d.ts │ ├── functions.js │ ├── functiontype-rest-uknown.d.ts │ ├── functiontype-rest-uknown.js │ ├── functiontype-rest.d.ts │ ├── functiontype-rest.js │ ├── generic-class.d.ts │ ├── generic-class.js │ ├── generic-function.d.ts │ ├── generic-function.js │ ├── generic-interface.d.ts │ ├── generic-interface.js │ ├── generic-method.d.ts │ ├── generic-method.js │ ├── generic-no-type-param.d.ts │ ├── generic-no-type-param.js │ ├── generic-wrong-type-param.d.ts │ ├── generic-wrong-type-param.js │ ├── generics.d.ts │ ├── generics.js │ ├── goog-global.d.ts │ ├── goog-global.js │ ├── goog.provide.d.ts │ ├── goog.provide.js │ ├── goog.string.d.ts │ ├── goog.string.js │ ├── ignore-list.d.ts │ ├── ignore-list.js │ ├── ignore-private.d.ts │ ├── ignore-private.js │ ├── interface-extends.d.ts │ ├── interface-extends.js │ ├── interface-implements.d.ts │ ├── interface-implements.js │ ├── interface-static.d.ts │ ├── interface-static.js │ ├── interface.d.ts │ ├── interface.js │ ├── literal-member.d.ts │ ├── literal-member.js │ ├── multi-functions.d.ts │ ├── multi-functions.js │ ├── multi-leading-comments.d.ts │ ├── multi-leading-comments.js │ ├── no-jsdoc-assignement.d.ts │ ├── no-jsdoc-assignement.js │ ├── no-jsdoc-function.d.ts │ ├── no-jsdoc-function.js │ ├── nodelist.d.ts │ ├── nodelist.js │ ├── null.d.ts │ ├── null.js │ ├── nullable-literal.d.ts │ ├── nullable-literal.js │ ├── nullable.d.ts │ ├── nullable.js │ ├── object.d.ts │ ├── object.js │ ├── optional.d.ts │ ├── optional.js │ ├── record-type.d.ts │ ├── record-type.js │ ├── record.d.ts │ ├── record.js │ ├── reserved-words.d.ts │ ├── reserved-words.js │ ├── roots.d.ts │ ├── roots.js │ ├── typedef-private.d.ts │ ├── typedef-private.js │ ├── typedef-record.d.ts │ ├── typedef-record.js │ ├── typedef-union.d.ts │ ├── typedef-union.js │ ├── undefined.d.ts │ ├── undefined.js │ ├── union.d.ts │ ├── union.js │ ├── varargs.d.ts │ ├── varargs.js │ ├── void.d.ts │ └── void.js └── parse.js ├── tsconfig.json └── tslint.js /.eslintignore: -------------------------------------------------------------------------------- 1 | /test/fixtures 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["teppeis/node-v8", "teppeis/+prettier", "teppeis/+mocha"], 3 | "rules": { 4 | "node/no-missing-require": ["error", { 5 | "tryExtensions": [".ts", ".js", ".json", ".node"] 6 | }] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | /lib 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "closure-library"] 2 | path = closure-library 3 | url = git://github.com/teppeis/closure-library.git 4 | branch = fix 5 | [submodule "closure-library.d.ts"] 6 | path = closure-library.d.ts 7 | url = git://github.com/teppeis/closure-library.d.ts.git 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "10" 5 | - "11" 6 | git: 7 | submodules: false 8 | sudo: false 9 | -------------------------------------------------------------------------------- /@types/@teppeis/doctrine/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for doctrine the JSDoc parser 2 | // Project: https://github.com/eslint/doctrine 3 | // Definitions by: rictic 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | /** 7 | * Doctrine is a JSDoc parser that parses documentation comments from JavaScript 8 | * (you need to pass in the comment, not a whole JavaScript file). 9 | */ 10 | 11 | /** 12 | * Parse the given content as a jsdoc comment. 13 | */ 14 | export function parse(content: string, options?: Options): Annotation; 15 | /** 16 | * Remove /*, *, and * / from jsdoc. 17 | */ 18 | export function unwrapComment(doc: string): string; 19 | 20 | interface Options { 21 | /** 22 | * Set to `true` to delete the leading `/**`, any `*` that begins a line, 23 | * and the trailing `* /` from the source text. Default: `false`. 24 | */ 25 | unwrap?: boolean; 26 | /** 27 | * An array of tags to return. When specified, Doctrine returns 28 | * only tags in this array. For example, if `tags` is `["param"]`, then only 29 | * `@param` tags will be returned. Default: `null`. 30 | */ 31 | tags?: string[]; 32 | /** 33 | * set to `true` to keep parsing even when syntax errors occur. Default: 34 | * `false`. 35 | */ 36 | recoverable?: boolean; 37 | /** 38 | * Set to `true` to allow optional parameters to be specified in brackets 39 | * (`@param {string} [foo]`). Default: `false`. 40 | */ 41 | sloppy?: boolean; 42 | /** 43 | * Set to `true` to throw an error when syntax errors occur. If false then 44 | * errors will be added to `tag.errors` instead. 45 | */ 46 | strict?: boolean; 47 | /** 48 | * Set to `true` to preserve leading and trailing whitespace when extracting 49 | * comment text. 50 | */ 51 | preserveWhitespace?: boolean; 52 | /** 53 | * Set to `true` to add `lineNumber` to each node, specifying the line on 54 | * which the node is found in the source. Default: `false`. 55 | */ 56 | lineNumbers?: boolean; 57 | } 58 | 59 | /** 60 | * Represents a parsed jsdoc comment. 61 | */ 62 | interface Annotation { 63 | /** The overall description of the thing being documented. */ 64 | description: string; 65 | tags: Tag[]; 66 | } 67 | 68 | /** 69 | * Represents a single jsdoc tag. 70 | * 71 | * So for example: 72 | * `@ param {{ok:String}} userName` 73 | * (ignore the space after the @) 74 | * 75 | * Would be represented as: 76 | * 77 | * {title: 'param', name: 'userName', 78 | * type: {type: 'RecordType", fields: [ 79 | * {type: 'FieldType', 80 | * key: 'ok', 81 | * value: {type: 'NameExpression', name: 'String'}}]}} 82 | * 83 | */ 84 | export interface Tag { 85 | /** The title of the jsdoc tag. e.g. `@foo` will have a title of 'foo'. */ 86 | title: string; 87 | /** The name of the thing this tag is documenting, if any. */ 88 | name?: string; 89 | /** The description of the thing this tag is documenting. */ 90 | description: string|null; 91 | /** The type of the thing this tag is documenting. */ 92 | type?: Type|null; 93 | kind?: string; 94 | /** Any errors that were encountered in parsing the tag. */ 95 | errors?: string[]; 96 | } 97 | 98 | export type Type = 99 | (type.AllLiteral | type.ArrayType | type.FieldType | type.FunctionType | 100 | type.NameExpression | type.NonNullableType | type.NullableLiteral | 101 | type.NullableType | type.NullLiteral | type.OptionalType | 102 | type.ParameterType | type.RecordType | type.RestType | 103 | type.TypeApplication | type.UndefinedLiteral | type.UnionType | 104 | type.VoidLiteral); 105 | 106 | export module type { 107 | export interface AllLiteral { type: 'AllLiteral' } 108 | export interface ArrayType { type: 'ArrayType', elements: Type[] } 109 | export interface FieldType { type: 'FieldType', key: string, value?: Type } 110 | export interface FunctionType { 111 | type: 'FunctionType'; 112 | 'this': Type; 113 | 'new': Type; 114 | params: Type[]; 115 | result: Type; 116 | } 117 | export interface NameExpression { type: 'NameExpression', name: string } 118 | export interface NonNullableType { 119 | type: 'NonNullableType', prefix: boolean, expression: Type 120 | } 121 | export interface NullableLiteral { type: 'NullableLiteral' } 122 | export interface NullableType { 123 | type: 'NullableType', prefix: boolean, expression: Type 124 | } 125 | export interface NullLiteral { type: 'NullLiteral' } 126 | export interface OptionalType { type: 'OptionalType', expression: Type } 127 | export interface ParameterType { 128 | type: 'ParameterType', name: string, expression: Type 129 | } 130 | export interface RecordType { type: 'RecordType', fields: FieldType[] } 131 | export interface RestType { 132 | type: 'RestType'; 133 | expression?: Type; 134 | } 135 | export interface TypeApplication { 136 | type: 'TypeApplication', expression: Type, applications: Type[] 137 | } 138 | export interface UndefinedLiteral { type: 'UndefinedLiteral' } 139 | export interface UnionType { type: 'UnionType', elements: Type[] } 140 | export interface VoidLiteral { type: 'VoidLiteral' } 141 | 142 | export function stringify(type: Type): string; 143 | export function parseType(src: string, options?: {midstream: boolean}): Type; 144 | export function parseParamType( 145 | src: string, options?: {midstream: boolean}): Type; 146 | 147 | export const Syntax: { 148 | NullableLiteral: 'NullableLiteral', 149 | AllLiteral: 'AllLiteral', 150 | NullLiteral: 'NullLiteral', 151 | UndefinedLiteral: 'UndefinedLiteral', 152 | VoidLiteral: 'VoidLiteral', 153 | UnionType: 'UnionType', 154 | ArrayType: 'ArrayType', 155 | RecordType: 'RecordType', 156 | FieldType: 'FieldType', 157 | FunctionType: 'FunctionType', 158 | ParameterType: 'ParameterType', 159 | RestType: 'RestType', 160 | NonNullableType: 'NonNullableType', 161 | OptionalType: 'OptionalType', 162 | NullableType: 'NullableType', 163 | NameExpression: 'NameExpression', 164 | TypeApplication: 'TypeApplication' 165 | } 166 | } 167 | 168 | export const version: string; 169 | export const parseType: typeof type.parseType; 170 | export const parseParamType: typeof type.parseParamType; 171 | export const Syntax: typeof type.Syntax; 172 | -------------------------------------------------------------------------------- /@types/esprima/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Esprima 4.0 2 | // Project: http://esprima.org 3 | // Definitions by: teppeis , RReverser , peter-scott 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | import * as ESTree from 'estree'; 7 | 8 | export const version: string; 9 | 10 | export function parseScript(input: string, config?: ParseOptions, delegate?: (node: ESTree.Node, meta: any) => void): Program; 11 | export function parseModule(input: string, config?: ParseOptions, delegate?: (node: ESTree.Node, meta: any) => void): Program; 12 | export function tokenize(input: string, config?: TokenizeOptions): Token[]; 13 | 14 | export interface Program extends ESTree.Program { 15 | tokens?: Token[]; 16 | } 17 | 18 | export interface Token { 19 | type: string; 20 | value: string; 21 | } 22 | 23 | export interface ParseOptions { 24 | jsx?: boolean; 25 | range?: boolean; 26 | loc?: boolean; 27 | tolerant?: boolean; 28 | tokens?: boolean; 29 | comment?: boolean; 30 | attachComment?: boolean; 31 | } 32 | 33 | export interface TokenizeOptions { 34 | tolerant?: boolean; 35 | range?: boolean; 36 | loc?: boolean; 37 | comment?: boolean; 38 | } 39 | 40 | export const Syntax: { 41 | ArrayExpression: 'ArrayExpression', 42 | ArrayPattern: 'ArrayPattern', 43 | ArrowFunctionExpression: 'ArrowFunctionExpression', 44 | AssignmentExpression: 'AssignmentExpression', 45 | AssignmentPattern: 'AssignmentPattern', 46 | AwaitExpression: 'AwaitExpression', 47 | BinaryExpression: 'BinaryExpression', 48 | BlockStatement: 'BlockStatement', 49 | BreakStatement: 'BreakStatement', 50 | CallExpression: 'CallExpression', 51 | CatchClause: 'CatchClause', 52 | ClassBody: 'ClassBody', 53 | ClassDeclaration: 'ClassDeclaration', 54 | ClassExpression: 'ClassExpression', 55 | ConditionalExpression: 'ConditionalExpression', 56 | ContinueStatement: 'ContinueStatement', 57 | DebuggerStatement: 'DebuggerStatement', 58 | DoWhileStatement: 'DoWhileStatement', 59 | EmptyStatement: 'EmptyStatement', 60 | ExportAllDeclaration: 'ExportAllDeclaration', 61 | ExportDefaultDeclaration: 'ExportDefaultDeclaration', 62 | ExportNamedDeclaration: 'ExportNamedDeclaration', 63 | ExportSpecifier: 'ExportSpecifier', 64 | ExpressionStatement: 'ExpressionStatement', 65 | ForInStatement: 'ForInStatement', 66 | ForOfStatement: 'ForOfStatement', 67 | ForStatement: 'ForStatement', 68 | FunctionDeclaration: 'FunctionDeclaration', 69 | FunctionExpression: 'FunctionExpression', 70 | Identifier: 'Identifier', 71 | IfStatement: 'IfStatement', 72 | Import: 'Import', 73 | ImportDeclaration: 'ImportDeclaration', 74 | ImportDefaultSpecifier: 'ImportDefaultSpecifier', 75 | ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', 76 | ImportSpecifier: 'ImportSpecifier', 77 | LabeledStatement: 'LabeledStatement', 78 | Literal: 'Literal', 79 | LogicalExpression: 'LogicalExpression', 80 | MemberExpression: 'MemberExpression', 81 | MetaProperty: 'MetaProperty', 82 | MethodDefinition: 'MethodDefinition', 83 | NewExpression: 'NewExpression', 84 | ObjectExpression: 'ObjectExpression', 85 | ObjectPattern: 'ObjectPattern', 86 | Program: 'Program', 87 | Property: 'Property', 88 | RestElement: 'RestElement', 89 | ReturnStatement: 'ReturnStatement', 90 | SequenceExpression: 'SequenceExpression', 91 | SpreadElement: 'SpreadElement', 92 | Super: 'Super', 93 | SwitchCase: 'SwitchCase', 94 | SwitchStatement: 'SwitchStatement', 95 | TaggedTemplateExpression: 'TaggedTemplateExpression', 96 | TemplateElement: 'TemplateElement', 97 | TemplateLiteral: 'TemplateLiteral', 98 | ThisExpression: 'ThisExpression', 99 | ThrowStatement: 'ThrowStatement', 100 | TryStatement: 'TryStatement', 101 | UnaryExpression: 'UnaryExpression', 102 | UpdateExpression: 'UpdateExpression', 103 | VariableDeclaration: 'VariableDeclaration', 104 | VariableDeclarator: 'VariableDeclarator', 105 | WhileStatement: 'WhileStatement', 106 | WithStatement: 'WithStatement', 107 | YieldExpression: 'YieldExpression' 108 | }; 109 | -------------------------------------------------------------------------------- /@types/espurify/index.d.ts: -------------------------------------------------------------------------------- 1 | import * as ESTree from 'estree'; 2 | 3 | export default function espurify(originalAst: ESTree.Node): ESTree.Node; -------------------------------------------------------------------------------- /@types/estraverse/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for estraverse 2 | // Project: https://github.com/estools/estraverse 3 | // Definitions by: Sanex3339 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | import * as ESTree from 'estree'; 7 | 8 | export interface Visitor { 9 | enter?: (this: Controller, node: ESTree.Node, parentNode: ESTree.Node | null) => VisitorOption | ESTree.Node | void; 10 | leave?: (this: Controller, node: ESTree.Node, parentNode: ESTree.Node | null) => VisitorOption | ESTree.Node | void; 11 | fallback?: 'iteration'|((this: Controller, node: ESTree.Node) => string[]); 12 | keys?: {[nodeType: string]: string[];}; 13 | } 14 | 15 | export enum VisitorOption {Skip, Break, Remove} 16 | 17 | export function traverse(root: ESTree.Node, visitor: Visitor): void; 18 | export function replace(root: ESTree.Node, visitor: Visitor): ESTree.Node; 19 | 20 | export class Controller { 21 | path(): string[]|null; 22 | type(): string; 23 | parents(): ESTree.Node[]; 24 | current(): ESTree.Node; 25 | notify(flag: VisitorOption): void; 26 | skip(): void; 27 | break(): void; 28 | remove(): void; 29 | traverse(root: ESTree.Node, visitor: Visitor): void; 30 | replace(root: ESTree.Node, visitor: Visitor): ESTree.Node; 31 | } 32 | 33 | export const Syntax: { 34 | AssignmentExpression: 'AssignmentExpression', 35 | AssignmentPattern: 'AssignmentPattern', 36 | ArrayExpression: 'ArrayExpression', 37 | ArrayPattern: 'ArrayPattern', 38 | ArrowFunctionExpression: 'ArrowFunctionExpression', 39 | AwaitExpression: 'AwaitExpression', // CAUTION: It's deferred to ES7. 40 | BlockStatement: 'BlockStatement', 41 | BinaryExpression: 'BinaryExpression', 42 | BreakStatement: 'BreakStatement', 43 | CallExpression: 'CallExpression', 44 | CatchClause: 'CatchClause', 45 | ClassBody: 'ClassBody', 46 | ClassDeclaration: 'ClassDeclaration', 47 | ClassExpression: 'ClassExpression', 48 | ComprehensionBlock: 'ComprehensionBlock', // CAUTION: It's deferred to ES7. 49 | ComprehensionExpression: 'ComprehensionExpression', // CAUTION: It's deferred to ES7. 50 | ConditionalExpression: 'ConditionalExpression', 51 | ContinueStatement: 'ContinueStatement', 52 | DebuggerStatement: 'DebuggerStatement', 53 | DirectiveStatement: 'DirectiveStatement', 54 | DoWhileStatement: 'DoWhileStatement', 55 | EmptyStatement: 'EmptyStatement', 56 | ExportAllDeclaration: 'ExportAllDeclaration', 57 | ExportDefaultDeclaration: 'ExportDefaultDeclaration', 58 | ExportNamedDeclaration: 'ExportNamedDeclaration', 59 | ExportSpecifier: 'ExportSpecifier', 60 | ExpressionStatement: 'ExpressionStatement', 61 | ForStatement: 'ForStatement', 62 | ForInStatement: 'ForInStatement', 63 | ForOfStatement: 'ForOfStatement', 64 | FunctionDeclaration: 'FunctionDeclaration', 65 | FunctionExpression: 'FunctionExpression', 66 | GeneratorExpression: 'GeneratorExpression', // CAUTION: It's deferred to ES7. 67 | Identifier: 'Identifier', 68 | IfStatement: 'IfStatement', 69 | ImportDeclaration: 'ImportDeclaration', 70 | ImportDefaultSpecifier: 'ImportDefaultSpecifier', 71 | ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', 72 | ImportSpecifier: 'ImportSpecifier', 73 | Literal: 'Literal', 74 | LabeledStatement: 'LabeledStatement', 75 | LogicalExpression: 'LogicalExpression', 76 | MemberExpression: 'MemberExpression', 77 | MetaProperty: 'MetaProperty', 78 | MethodDefinition: 'MethodDefinition', 79 | ModuleSpecifier: 'ModuleSpecifier', 80 | NewExpression: 'NewExpression', 81 | ObjectExpression: 'ObjectExpression', 82 | ObjectPattern: 'ObjectPattern', 83 | Program: 'Program', 84 | Property: 'Property', 85 | RestElement: 'RestElement', 86 | ReturnStatement: 'ReturnStatement', 87 | SequenceExpression: 'SequenceExpression', 88 | SpreadElement: 'SpreadElement', 89 | Super: 'Super', 90 | SwitchStatement: 'SwitchStatement', 91 | SwitchCase: 'SwitchCase', 92 | TaggedTemplateExpression: 'TaggedTemplateExpression', 93 | TemplateElement: 'TemplateElement', 94 | TemplateLiteral: 'TemplateLiteral', 95 | ThisExpression: 'ThisExpression', 96 | ThrowStatement: 'ThrowStatement', 97 | TryStatement: 'TryStatement', 98 | UnaryExpression: 'UnaryExpression', 99 | UpdateExpression: 'UpdateExpression', 100 | VariableDeclaration: 'VariableDeclaration', 101 | VariableDeclarator: 'VariableDeclarator', 102 | WhileStatement: 'WhileStatement', 103 | WithStatement: 'WithStatement', 104 | YieldExpression: 'YieldExpression', 105 | } 106 | 107 | export const VisitorKeys: { 108 | AssignmentExpression: ['left', 'right'], 109 | AssignmentPattern: ['left', 'right'], 110 | ArrayExpression: ['elements'], 111 | ArrayPattern: ['elements'], 112 | ArrowFunctionExpression: ['params', 'body'], 113 | AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7. 114 | BlockStatement: ['body'], 115 | BinaryExpression: ['left', 'right'], 116 | BreakStatement: ['label'], 117 | CallExpression: ['callee', 'arguments'], 118 | CatchClause: ['param', 'body'], 119 | ClassBody: ['body'], 120 | ClassDeclaration: ['id', 'superClass', 'body'], 121 | ClassExpression: ['id', 'superClass', 'body'], 122 | ComprehensionBlock: ['left', 'right'], // CAUTION: It's deferred to ES7. 123 | ComprehensionExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. 124 | ConditionalExpression: ['test', 'consequent', 'alternate'], 125 | ContinueStatement: ['label'], 126 | DebuggerStatement: [], 127 | DirectiveStatement: [], 128 | DoWhileStatement: ['body', 'test'], 129 | EmptyStatement: [], 130 | ExportAllDeclaration: ['source'], 131 | ExportDefaultDeclaration: ['declaration'], 132 | ExportNamedDeclaration: ['declaration', 'specifiers', 'source'], 133 | ExportSpecifier: ['exported', 'local'], 134 | ExpressionStatement: ['expression'], 135 | ForStatement: ['init', 'test', 'update', 'body'], 136 | ForInStatement: ['left', 'right', 'body'], 137 | ForOfStatement: ['left', 'right', 'body'], 138 | FunctionDeclaration: ['id', 'params', 'body'], 139 | FunctionExpression: ['id', 'params', 'body'], 140 | GeneratorExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. 141 | Identifier: [], 142 | IfStatement: ['test', 'consequent', 'alternate'], 143 | ImportDeclaration: ['specifiers', 'source'], 144 | ImportDefaultSpecifier: ['local'], 145 | ImportNamespaceSpecifier: ['local'], 146 | ImportSpecifier: ['imported', 'local'], 147 | Literal: [], 148 | LabeledStatement: ['label', 'body'], 149 | LogicalExpression: ['left', 'right'], 150 | MemberExpression: ['object', 'property'], 151 | MetaProperty: ['meta', 'property'], 152 | MethodDefinition: ['key', 'value'], 153 | ModuleSpecifier: [], 154 | NewExpression: ['callee', 'arguments'], 155 | ObjectExpression: ['properties'], 156 | ObjectPattern: ['properties'], 157 | Program: ['body'], 158 | Property: ['key', 'value'], 159 | RestElement: [ 'argument' ], 160 | ReturnStatement: ['argument'], 161 | SequenceExpression: ['expressions'], 162 | SpreadElement: ['argument'], 163 | Super: [], 164 | SwitchStatement: ['discriminant', 'cases'], 165 | SwitchCase: ['test', 'consequent'], 166 | TaggedTemplateExpression: ['tag', 'quasi'], 167 | TemplateElement: [], 168 | TemplateLiteral: ['quasis', 'expressions'], 169 | ThisExpression: [], 170 | ThrowStatement: ['argument'], 171 | TryStatement: ['block', 'handler', 'finalizer'], 172 | UnaryExpression: ['argument'], 173 | UpdateExpression: ['argument'], 174 | VariableDeclaration: ['declarations'], 175 | VariableDeclarator: ['id', 'init'], 176 | WhileStatement: ['test', 'body'], 177 | WithStatement: ['object', 'body'], 178 | YieldExpression: ['argument'] 179 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # closure-ts 2 | 3 | [![npm Version][npm-image]][npm-url] 4 | ![Node.js Version Support][node-version] 5 | [![Build Status](https://travis-ci.org/teppeis/closure-ts.svg?branch=master)](https://travis-ci.org/teppeis/closure-ts) 6 | [![Dependency Status][deps-image]][deps-url] 7 | ![License][license] 8 | 9 | > Generates TypeScript declaration files (.d.ts) from [Closure Library JSDoc annotations](https://developers.google.com/closure/compiler/docs/js-for-compiler). 10 | 11 | The result is [closure-library.d.ts](https://github.com/teppeis/closure-library.d.ts 'teppeis/closure-library.d.ts'). 12 | 13 | ## Example 14 | 15 | From this JavaScript code with annotations, 16 | 17 | ```javascript 18 | /** 19 | * Truncates a string to a certain length. 20 | * @param {string} str 21 | * @param {number} chars 22 | * @param {boolean=} opt_protectEscapedCharacters 23 | * @return {string} 24 | */ 25 | goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) { 26 | // ... 27 | }; 28 | ``` 29 | 30 | closure-ts generates this declaration file (.d.ts). 31 | 32 | ```javascript 33 | declare module goog.string { 34 | /** 35 | * Truncates a string to a certain length. 36 | * @param {string} str 37 | * @param {number} chars 38 | * @param {boolean=} opt_protectEscapedCharacters 39 | * @return {string} 40 | */ 41 | function truncate(str: string, chars: number, opt_protectEscapedCharacters?: boolean): string; 42 | } 43 | ``` 44 | 45 | ## Usage 46 | 47 | ```bash 48 | $ closurets some-jsdoced-code.js 49 | $ ls 50 | some-jsdoced-code.d.ts 51 | some-jsdoced-code.js 52 | ``` 53 | 54 | ## Project status 55 | 56 | Just PoC 57 | 58 | ### Implemented 59 | 60 | - Variable with `@type` 61 | - Function with `@param` and `@return` 62 | - Namespace to TypeScript `module` 63 | - Classes (`@constructor` and `@extends`) 64 | - Enum with `@enum` to TypeScrip type alias and variables 65 | - Convert `*` and `?` to `any` 66 | - Generic type like `Array` 67 | - Generic classes and function with `@template` 68 | - Union type 69 | - Record type 70 | - Rest parameters in `@param` and FunctionType 71 | - Optional parameters 72 | - Exclude `@private` definitions 73 | - Convert `@typedef` to `type` 74 | - Convert `@record` to `interface` 75 | - Convert `Object` to `{[index: string]: Foo}` 76 | - Ignore features TypeScript doesn't have 77 | - `@this`, `this:` and `new:` of function type 78 | - Nullable, Non-Nullable 79 | 80 | ### TODO 81 | 82 | - `@lends` 83 | - Dependencies of Closure Library files 84 | - One stop build system with Grunt or Gulp 85 | 86 | [npm-image]: https://img.shields.io/npm/v/closure-ts.svg 87 | [npm-url]: https://npmjs.org/package/closure-ts 88 | [npm-downloads-image]: https://img.shields.io/npm/dm/closure-ts.svg 89 | [deps-image]: https://img.shields.io/david/teppeis/closure-ts.svg 90 | [deps-url]: https://david-dm.org/teppeis/closure-ts 91 | [node-version]: https://img.shields.io/badge/Node.js%20support-v8,v10,v11-brightgreen.svg 92 | [license]: https://img.shields.io/npm/l/closure-ts.svg 93 | -------------------------------------------------------------------------------- /bin/check-error.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASEDIR=$(cd "$(dirname "$0")/.."; pwd;) || exit 1 4 | 5 | npx typescript@3.1 --noEmit --lib DOM,ES2018,DOM.Iterable "$BASEDIR/test/all.ts" 2>&1 | \ 6 | sed -e 's/\/.*\/closure-ts\///g' | \ 7 | sed -e '/^npx: /d' | \ 8 | tee "$BASEDIR/misc/error.log" 9 | -------------------------------------------------------------------------------- /bin/closurets.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const cli = require('../lib/cli').default; 6 | cli(process.argv, process.stdout, process.stderr, process.exit); 7 | -------------------------------------------------------------------------------- /bin/generate-alldts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BASEDIR=$(cd "$(dirname "$0")/.."; pwd;) || exit 1 4 | DEFINITION_DIR=$BASEDIR/closure-library.d.ts 5 | 6 | find "$DEFINITION_DIR" -type f -name '*.d.ts' | \ 7 | grep -v all.d.ts | \ 8 | grep -v closure/goog/net/fetchxmlhttpfactory.d.ts | \ 9 | sort | \ 10 | sed -e 's/.*\/closure-library.d.ts\//\/\/\/ /g' \ 11 | > "$DEFINITION_DIR/all.d.ts" 12 | -------------------------------------------------------------------------------- /bin/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")/.." || exit 1 4 | BASEDIR=. 5 | 6 | find $BASEDIR/closure-library.d.ts -type f -name '*.d.ts'|grep -v '/externs/'|xargs rm 7 | find $BASEDIR/closure-library/closure/goog $BASEDIR/closure-library/third_party/closure/goog -type f -name '*.js'|sort| 8 | grep -v /demos/| 9 | grep -v /testdata/| 10 | grep -v '_test.js$'| 11 | grep -v 'tester.js$'| 12 | grep -v '_perf.js$'| 13 | diff --unchanged-line-format='' --new-line-format='' - ./misc/ignore.txt| 14 | diff --unchanged-line-format='' --new-line-format='' - ./misc/goog.module.txt| 15 | diff --unchanged-line-format='' --new-line-format='' - ./misc/goog.module.get.txt| 16 | diff --unchanged-line-format='' --new-line-format='' - ./misc/goog.scope.txt| 17 | xargs $BASEDIR/bin/closurets.js 18 | cp $BASEDIR/builtin.d.ts $BASEDIR/closure-library.d.ts/externs/ 19 | $BASEDIR/bin/generate-alldts.sh 20 | $BASEDIR/bin/check-error.sh 21 | -------------------------------------------------------------------------------- /builtin.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | type globalEventTarget = EventTarget; 3 | } 4 | 5 | interface IArrayLike { 6 | length: number; 7 | [key: number]: VALUE; 8 | } 9 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/dom/tagname.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * Enum of all html tag names specified by the W3C HTML4.01 and HTML5 5 | * specifications. 6 | * @enum {string} 7 | */ 8 | export interface TagName { 9 | A: string; 10 | ABBR: string; 11 | ACRONYM: string; 12 | ADDRESS: string; 13 | APPLET: string; 14 | AREA: string; 15 | ARTICLE: string; 16 | ASIDE: string; 17 | AUDIO: string; 18 | B: string; 19 | BASE: string; 20 | BASEFONT: string; 21 | BDI: string; 22 | BDO: string; 23 | BIG: string; 24 | BLOCKQUOTE: string; 25 | BODY: string; 26 | BR: string; 27 | BUTTON: string; 28 | CANVAS: string; 29 | CAPTION: string; 30 | CENTER: string; 31 | CITE: string; 32 | CODE: string; 33 | COL: string; 34 | COLGROUP: string; 35 | COMMAND: string; 36 | DATA: string; 37 | DATALIST: string; 38 | DD: string; 39 | DEL: string; 40 | DETAILS: string; 41 | DFN: string; 42 | DIALOG: string; 43 | DIR: string; 44 | DIV: string; 45 | DL: string; 46 | DT: string; 47 | EM: string; 48 | EMBED: string; 49 | FIELDSET: string; 50 | FIGCAPTION: string; 51 | FIGURE: string; 52 | FONT: string; 53 | FOOTER: string; 54 | FORM: string; 55 | FRAME: string; 56 | FRAMESET: string; 57 | H1: string; 58 | H2: string; 59 | H3: string; 60 | H4: string; 61 | H5: string; 62 | H6: string; 63 | HEAD: string; 64 | HEADER: string; 65 | HGROUP: string; 66 | HR: string; 67 | HTML: string; 68 | I: string; 69 | IFRAME: string; 70 | IMG: string; 71 | INPUT: string; 72 | INS: string; 73 | ISINDEX: string; 74 | KBD: string; 75 | KEYGEN: string; 76 | LABEL: string; 77 | LEGEND: string; 78 | LI: string; 79 | LINK: string; 80 | MAP: string; 81 | MARK: string; 82 | MATH: string; 83 | MENU: string; 84 | META: string; 85 | METER: string; 86 | NAV: string; 87 | NOFRAMES: string; 88 | NOSCRIPT: string; 89 | OBJECT: string; 90 | OL: string; 91 | OPTGROUP: string; 92 | OPTION: string; 93 | OUTPUT: string; 94 | P: string; 95 | PARAM: string; 96 | PRE: string; 97 | PROGRESS: string; 98 | Q: string; 99 | RP: string; 100 | RT: string; 101 | RUBY: string; 102 | S: string; 103 | SAMP: string; 104 | SCRIPT: string; 105 | SECTION: string; 106 | SELECT: string; 107 | SMALL: string; 108 | SOURCE: string; 109 | SPAN: string; 110 | STRIKE: string; 111 | STRONG: string; 112 | STYLE: string; 113 | SUB: string; 114 | SUMMARY: string; 115 | SUP: string; 116 | SVG: string; 117 | TABLE: string; 118 | TBODY: string; 119 | TD: string; 120 | TEXTAREA: string; 121 | TFOOT: string; 122 | TH: string; 123 | THEAD: string; 124 | TIME: string; 125 | TITLE: string; 126 | TR: string; 127 | TRACK: string; 128 | TT: string; 129 | U: string; 130 | UL: string; 131 | VAR: string; 132 | VIDEO: string; 133 | WBR: string; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/dom/tagname.js: -------------------------------------------------------------------------------- 1 | // Copyright 2007 The Closure Library Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @fileoverview Defines the goog.dom.TagName enum. This enumerates 17 | * all HTML tag names specified in either the the W3C HTML 4.01 index of 18 | * elements or the HTML5 draft specification. 19 | * 20 | * References: 21 | * http://www.w3.org/TR/html401/index/elements.html 22 | * http://dev.w3.org/html5/spec/section-index.html 23 | * 24 | */ 25 | goog.provide('goog.dom.TagName'); 26 | 27 | 28 | /** 29 | * Enum of all html tag names specified by the W3C HTML4.01 and HTML5 30 | * specifications. 31 | * @enum {string} 32 | */ 33 | goog.dom.TagName = { 34 | A: 'A', 35 | ABBR: 'ABBR', 36 | ACRONYM: 'ACRONYM', 37 | ADDRESS: 'ADDRESS', 38 | APPLET: 'APPLET', 39 | AREA: 'AREA', 40 | ARTICLE: 'ARTICLE', 41 | ASIDE: 'ASIDE', 42 | AUDIO: 'AUDIO', 43 | B: 'B', 44 | BASE: 'BASE', 45 | BASEFONT: 'BASEFONT', 46 | BDI: 'BDI', 47 | BDO: 'BDO', 48 | BIG: 'BIG', 49 | BLOCKQUOTE: 'BLOCKQUOTE', 50 | BODY: 'BODY', 51 | BR: 'BR', 52 | BUTTON: 'BUTTON', 53 | CANVAS: 'CANVAS', 54 | CAPTION: 'CAPTION', 55 | CENTER: 'CENTER', 56 | CITE: 'CITE', 57 | CODE: 'CODE', 58 | COL: 'COL', 59 | COLGROUP: 'COLGROUP', 60 | COMMAND: 'COMMAND', 61 | DATA: 'DATA', 62 | DATALIST: 'DATALIST', 63 | DD: 'DD', 64 | DEL: 'DEL', 65 | DETAILS: 'DETAILS', 66 | DFN: 'DFN', 67 | DIALOG: 'DIALOG', 68 | DIR: 'DIR', 69 | DIV: 'DIV', 70 | DL: 'DL', 71 | DT: 'DT', 72 | EM: 'EM', 73 | EMBED: 'EMBED', 74 | FIELDSET: 'FIELDSET', 75 | FIGCAPTION: 'FIGCAPTION', 76 | FIGURE: 'FIGURE', 77 | FONT: 'FONT', 78 | FOOTER: 'FOOTER', 79 | FORM: 'FORM', 80 | FRAME: 'FRAME', 81 | FRAMESET: 'FRAMESET', 82 | H1: 'H1', 83 | H2: 'H2', 84 | H3: 'H3', 85 | H4: 'H4', 86 | H5: 'H5', 87 | H6: 'H6', 88 | HEAD: 'HEAD', 89 | HEADER: 'HEADER', 90 | HGROUP: 'HGROUP', 91 | HR: 'HR', 92 | HTML: 'HTML', 93 | I: 'I', 94 | IFRAME: 'IFRAME', 95 | IMG: 'IMG', 96 | INPUT: 'INPUT', 97 | INS: 'INS', 98 | ISINDEX: 'ISINDEX', 99 | KBD: 'KBD', 100 | KEYGEN: 'KEYGEN', 101 | LABEL: 'LABEL', 102 | LEGEND: 'LEGEND', 103 | LI: 'LI', 104 | LINK: 'LINK', 105 | MAP: 'MAP', 106 | MARK: 'MARK', 107 | MATH: 'MATH', 108 | MENU: 'MENU', 109 | META: 'META', 110 | METER: 'METER', 111 | NAV: 'NAV', 112 | NOFRAMES: 'NOFRAMES', 113 | NOSCRIPT: 'NOSCRIPT', 114 | OBJECT: 'OBJECT', 115 | OL: 'OL', 116 | OPTGROUP: 'OPTGROUP', 117 | OPTION: 'OPTION', 118 | OUTPUT: 'OUTPUT', 119 | P: 'P', 120 | PARAM: 'PARAM', 121 | PRE: 'PRE', 122 | PROGRESS: 'PROGRESS', 123 | Q: 'Q', 124 | RP: 'RP', 125 | RT: 'RT', 126 | RUBY: 'RUBY', 127 | S: 'S', 128 | SAMP: 'SAMP', 129 | SCRIPT: 'SCRIPT', 130 | SECTION: 'SECTION', 131 | SELECT: 'SELECT', 132 | SMALL: 'SMALL', 133 | SOURCE: 'SOURCE', 134 | SPAN: 'SPAN', 135 | STRIKE: 'STRIKE', 136 | STRONG: 'STRONG', 137 | STYLE: 'STYLE', 138 | SUB: 'SUB', 139 | SUMMARY: 'SUMMARY', 140 | SUP: 'SUP', 141 | SVG: 'SVG', 142 | TABLE: 'TABLE', 143 | TBODY: 'TBODY', 144 | TD: 'TD', 145 | TEXTAREA: 'TEXTAREA', 146 | TFOOT: 'TFOOT', 147 | TH: 'TH', 148 | THEAD: 'THEAD', 149 | TIME: 'TIME', 150 | TITLE: 'TITLE', 151 | TR: 'TR', 152 | TRACK: 'TRACK', 153 | TT: 'TT', 154 | U: 'U', 155 | UL: 'UL', 156 | VAR: 'VAR', 157 | VIDEO: 'VIDEO', 158 | WBR: 'WBR' 159 | }; 160 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/coordinate.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.math { 2 | 3 | /** 4 | * Class for representing coordinates and positions. 5 | * @param {number=} opt_x Left, defaults to 0. 6 | * @param {number=} opt_y Top, defaults to 0. 7 | * @constructor 8 | */ 9 | export class Coordinate { 10 | constructor(opt_x?: number, opt_y?: number); 11 | 12 | /** 13 | * Returns a new copy of the coordinate. 14 | * @return {!goog.math.Coordinate} A clone of this coordinate. 15 | */ 16 | clone(): goog.math.Coordinate; 17 | 18 | /** 19 | * Compares coordinates for equality. 20 | * @param {goog.math.Coordinate} a A Coordinate. 21 | * @param {goog.math.Coordinate} b A Coordinate. 22 | * @return {boolean} True iff the coordinates are equal, or if both are null. 23 | */ 24 | static equals(a: goog.math.Coordinate, b: goog.math.Coordinate): boolean; 25 | 26 | /** 27 | * Returns the distance between two coordinates. 28 | * @param {!goog.math.Coordinate} a A Coordinate. 29 | * @param {!goog.math.Coordinate} b A Coordinate. 30 | * @return {number} The distance between {@code a} and {@code b}. 31 | */ 32 | static distance(a: goog.math.Coordinate, b: goog.math.Coordinate): number; 33 | 34 | /** 35 | * Returns the magnitude of a coordinate. 36 | * @param {!goog.math.Coordinate} a A Coordinate. 37 | * @return {number} The distance between the origin and {@code a}. 38 | */ 39 | static magnitude(a: goog.math.Coordinate): number; 40 | 41 | /** 42 | * Returns the angle from the origin to a coordinate. 43 | * @param {!goog.math.Coordinate} a A Coordinate. 44 | * @return {number} The angle, in degrees, clockwise from the positive X 45 | * axis to {@code a}. 46 | */ 47 | static azimuth(a: goog.math.Coordinate): number; 48 | 49 | /** 50 | * Returns the squared distance between two coordinates. Squared distances can 51 | * be used for comparisons when the actual value is not required. 52 | * 53 | * Performance note: eliminating the square root is an optimization often used 54 | * in lower-level languages, but the speed difference is not nearly as 55 | * pronounced in JavaScript (only a few percent.) 56 | * 57 | * @param {!goog.math.Coordinate} a A Coordinate. 58 | * @param {!goog.math.Coordinate} b A Coordinate. 59 | * @return {number} The squared distance between {@code a} and {@code b}. 60 | */ 61 | static squaredDistance(a: goog.math.Coordinate, b: goog.math.Coordinate): number; 62 | 63 | /** 64 | * Returns the difference between two coordinates as a new 65 | * goog.math.Coordinate. 66 | * @param {!goog.math.Coordinate} a A Coordinate. 67 | * @param {!goog.math.Coordinate} b A Coordinate. 68 | * @return {!goog.math.Coordinate} A Coordinate representing the difference 69 | * between {@code a} and {@code b}. 70 | */ 71 | static difference(a: goog.math.Coordinate, b: goog.math.Coordinate): goog.math.Coordinate; 72 | 73 | /** 74 | * Returns the sum of two coordinates as a new goog.math.Coordinate. 75 | * @param {!goog.math.Coordinate} a A Coordinate. 76 | * @param {!goog.math.Coordinate} b A Coordinate. 77 | * @return {!goog.math.Coordinate} A Coordinate representing the sum of the two 78 | * coordinates. 79 | */ 80 | static sum(a: goog.math.Coordinate, b: goog.math.Coordinate): goog.math.Coordinate; 81 | 82 | /** 83 | * Rounds the x and y fields to the next larger integer values. 84 | * @return {!goog.math.Coordinate} This coordinate with ceil'd fields. 85 | */ 86 | ceil(): goog.math.Coordinate; 87 | 88 | /** 89 | * Rounds the x and y fields to the next smaller integer values. 90 | * @return {!goog.math.Coordinate} This coordinate with floored fields. 91 | */ 92 | floor(): goog.math.Coordinate; 93 | 94 | /** 95 | * Rounds the x and y fields to the nearest integer values. 96 | * @return {!goog.math.Coordinate} This coordinate with rounded fields. 97 | */ 98 | round(): goog.math.Coordinate; 99 | 100 | /** 101 | * Translates this box by the given offsets. If a {@code goog.math.Coordinate} 102 | * is given, then the x and y values are translated by the coordinate's x and y. 103 | * Otherwise, x and y are translated by {@code tx} and {@code opt_ty} 104 | * respectively. 105 | * @param {number|goog.math.Coordinate} tx The value to translate x by or the 106 | * the coordinate to translate this coordinate by. 107 | * @param {number=} opt_ty The value to translate y by. 108 | * @return {!goog.math.Coordinate} This coordinate after translating. 109 | */ 110 | translate(tx: number, opt_ty?: number): goog.math.Coordinate; 111 | 112 | /** 113 | * Scales this coordinate by the given scale factors. The x and y values are 114 | * scaled by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} 115 | * is not given, then {@code sx} is used for both x and y. 116 | * @param {number} sx The scale factor to use for the x dimension. 117 | * @param {number=} opt_sy The scale factor to use for the y dimension. 118 | * @return {!goog.math.Coordinate} This coordinate after scaling. 119 | */ 120 | scale(sx: number, opt_sy?: number): goog.math.Coordinate; 121 | 122 | /** 123 | * Rotates this coordinate clockwise about the origin (or, optionally, the given 124 | * center) by the given angle, in radians. 125 | * @param {number} radians The angle by which to rotate this coordinate 126 | * clockwise about the given center, in radians. 127 | * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults 128 | * to (0, 0) if not given. 129 | */ 130 | rotateRadians(radians: number, opt_center?: goog.math.Coordinate): void; 131 | 132 | /** 133 | * Rotates this coordinate clockwise about the origin (or, optionally, the given 134 | * center) by the given angle, in degrees. 135 | * @param {number} degrees The angle by which to rotate this coordinate 136 | * clockwise about the given center, in degrees. 137 | * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults 138 | * to (0, 0) if not given. 139 | */ 140 | rotateDegrees(degrees: number, opt_center?: goog.math.Coordinate): void; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/coordinate.js: -------------------------------------------------------------------------------- 1 | // Copyright 2006 The Closure Library Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @fileoverview A utility class for representing two-dimensional positions. 17 | */ 18 | 19 | 20 | goog.provide('goog.math.Coordinate'); 21 | 22 | goog.require('goog.math'); 23 | 24 | 25 | 26 | /** 27 | * Class for representing coordinates and positions. 28 | * @param {number=} opt_x Left, defaults to 0. 29 | * @param {number=} opt_y Top, defaults to 0. 30 | * @constructor 31 | */ 32 | goog.math.Coordinate = function(opt_x, opt_y) { 33 | /** 34 | * X-value 35 | * @type {number} 36 | */ 37 | this.x = goog.isDef(opt_x) ? opt_x : 0; 38 | 39 | /** 40 | * Y-value 41 | * @type {number} 42 | */ 43 | this.y = goog.isDef(opt_y) ? opt_y : 0; 44 | }; 45 | 46 | 47 | /** 48 | * Returns a new copy of the coordinate. 49 | * @return {!goog.math.Coordinate} A clone of this coordinate. 50 | */ 51 | goog.math.Coordinate.prototype.clone = function() { 52 | return new goog.math.Coordinate(this.x, this.y); 53 | }; 54 | 55 | 56 | if (goog.DEBUG) { 57 | /** 58 | * Returns a nice string representing the coordinate. 59 | * @return {string} In the form (50, 73). 60 | * @override 61 | */ 62 | goog.math.Coordinate.prototype.toString = function() { 63 | return '(' + this.x + ', ' + this.y + ')'; 64 | }; 65 | } 66 | 67 | 68 | /** 69 | * Compares coordinates for equality. 70 | * @param {goog.math.Coordinate} a A Coordinate. 71 | * @param {goog.math.Coordinate} b A Coordinate. 72 | * @return {boolean} True iff the coordinates are equal, or if both are null. 73 | */ 74 | goog.math.Coordinate.equals = function(a, b) { 75 | if (a == b) { 76 | return true; 77 | } 78 | if (!a || !b) { 79 | return false; 80 | } 81 | return a.x == b.x && a.y == b.y; 82 | }; 83 | 84 | 85 | /** 86 | * Returns the distance between two coordinates. 87 | * @param {!goog.math.Coordinate} a A Coordinate. 88 | * @param {!goog.math.Coordinate} b A Coordinate. 89 | * @return {number} The distance between {@code a} and {@code b}. 90 | */ 91 | goog.math.Coordinate.distance = function(a, b) { 92 | var dx = a.x - b.x; 93 | var dy = a.y - b.y; 94 | return Math.sqrt(dx * dx + dy * dy); 95 | }; 96 | 97 | 98 | /** 99 | * Returns the magnitude of a coordinate. 100 | * @param {!goog.math.Coordinate} a A Coordinate. 101 | * @return {number} The distance between the origin and {@code a}. 102 | */ 103 | goog.math.Coordinate.magnitude = function(a) { 104 | return Math.sqrt(a.x * a.x + a.y * a.y); 105 | }; 106 | 107 | 108 | /** 109 | * Returns the angle from the origin to a coordinate. 110 | * @param {!goog.math.Coordinate} a A Coordinate. 111 | * @return {number} The angle, in degrees, clockwise from the positive X 112 | * axis to {@code a}. 113 | */ 114 | goog.math.Coordinate.azimuth = function(a) { 115 | return goog.math.angle(0, 0, a.x, a.y); 116 | }; 117 | 118 | 119 | /** 120 | * Returns the squared distance between two coordinates. Squared distances can 121 | * be used for comparisons when the actual value is not required. 122 | * 123 | * Performance note: eliminating the square root is an optimization often used 124 | * in lower-level languages, but the speed difference is not nearly as 125 | * pronounced in JavaScript (only a few percent.) 126 | * 127 | * @param {!goog.math.Coordinate} a A Coordinate. 128 | * @param {!goog.math.Coordinate} b A Coordinate. 129 | * @return {number} The squared distance between {@code a} and {@code b}. 130 | */ 131 | goog.math.Coordinate.squaredDistance = function(a, b) { 132 | var dx = a.x - b.x; 133 | var dy = a.y - b.y; 134 | return dx * dx + dy * dy; 135 | }; 136 | 137 | 138 | /** 139 | * Returns the difference between two coordinates as a new 140 | * goog.math.Coordinate. 141 | * @param {!goog.math.Coordinate} a A Coordinate. 142 | * @param {!goog.math.Coordinate} b A Coordinate. 143 | * @return {!goog.math.Coordinate} A Coordinate representing the difference 144 | * between {@code a} and {@code b}. 145 | */ 146 | goog.math.Coordinate.difference = function(a, b) { 147 | return new goog.math.Coordinate(a.x - b.x, a.y - b.y); 148 | }; 149 | 150 | 151 | /** 152 | * Returns the sum of two coordinates as a new goog.math.Coordinate. 153 | * @param {!goog.math.Coordinate} a A Coordinate. 154 | * @param {!goog.math.Coordinate} b A Coordinate. 155 | * @return {!goog.math.Coordinate} A Coordinate representing the sum of the two 156 | * coordinates. 157 | */ 158 | goog.math.Coordinate.sum = function(a, b) { 159 | return new goog.math.Coordinate(a.x + b.x, a.y + b.y); 160 | }; 161 | 162 | 163 | /** 164 | * Rounds the x and y fields to the next larger integer values. 165 | * @return {!goog.math.Coordinate} This coordinate with ceil'd fields. 166 | */ 167 | goog.math.Coordinate.prototype.ceil = function() { 168 | this.x = Math.ceil(this.x); 169 | this.y = Math.ceil(this.y); 170 | return this; 171 | }; 172 | 173 | 174 | /** 175 | * Rounds the x and y fields to the next smaller integer values. 176 | * @return {!goog.math.Coordinate} This coordinate with floored fields. 177 | */ 178 | goog.math.Coordinate.prototype.floor = function() { 179 | this.x = Math.floor(this.x); 180 | this.y = Math.floor(this.y); 181 | return this; 182 | }; 183 | 184 | 185 | /** 186 | * Rounds the x and y fields to the nearest integer values. 187 | * @return {!goog.math.Coordinate} This coordinate with rounded fields. 188 | */ 189 | goog.math.Coordinate.prototype.round = function() { 190 | this.x = Math.round(this.x); 191 | this.y = Math.round(this.y); 192 | return this; 193 | }; 194 | 195 | 196 | /** 197 | * Translates this box by the given offsets. If a {@code goog.math.Coordinate} 198 | * is given, then the x and y values are translated by the coordinate's x and y. 199 | * Otherwise, x and y are translated by {@code tx} and {@code opt_ty} 200 | * respectively. 201 | * @param {number|goog.math.Coordinate} tx The value to translate x by or the 202 | * the coordinate to translate this coordinate by. 203 | * @param {number=} opt_ty The value to translate y by. 204 | * @return {!goog.math.Coordinate} This coordinate after translating. 205 | */ 206 | goog.math.Coordinate.prototype.translate = function(tx, opt_ty) { 207 | if (tx instanceof goog.math.Coordinate) { 208 | this.x += tx.x; 209 | this.y += tx.y; 210 | } else { 211 | this.x += tx; 212 | if (goog.isNumber(opt_ty)) { 213 | this.y += opt_ty; 214 | } 215 | } 216 | return this; 217 | }; 218 | 219 | 220 | /** 221 | * Scales this coordinate by the given scale factors. The x and y values are 222 | * scaled by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} 223 | * is not given, then {@code sx} is used for both x and y. 224 | * @param {number} sx The scale factor to use for the x dimension. 225 | * @param {number=} opt_sy The scale factor to use for the y dimension. 226 | * @return {!goog.math.Coordinate} This coordinate after scaling. 227 | */ 228 | goog.math.Coordinate.prototype.scale = function(sx, opt_sy) { 229 | var sy = goog.isNumber(opt_sy) ? opt_sy : sx; 230 | this.x *= sx; 231 | this.y *= sy; 232 | return this; 233 | }; 234 | 235 | 236 | /** 237 | * Rotates this coordinate clockwise about the origin (or, optionally, the given 238 | * center) by the given angle, in radians. 239 | * @param {number} radians The angle by which to rotate this coordinate 240 | * clockwise about the given center, in radians. 241 | * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults 242 | * to (0, 0) if not given. 243 | */ 244 | goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) { 245 | var center = opt_center || new goog.math.Coordinate(0, 0); 246 | 247 | var x = this.x; 248 | var y = this.y; 249 | var cos = Math.cos(radians); 250 | var sin = Math.sin(radians); 251 | 252 | this.x = (x - center.x) * cos - (y - center.y) * sin + center.x; 253 | this.y = (x - center.x) * sin + (y - center.y) * cos + center.y; 254 | }; 255 | 256 | 257 | /** 258 | * Rotates this coordinate clockwise about the origin (or, optionally, the given 259 | * center) by the given angle, in degrees. 260 | * @param {number} degrees The angle by which to rotate this coordinate 261 | * clockwise about the given center, in degrees. 262 | * @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults 263 | * to (0, 0) if not given. 264 | */ 265 | goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) { 266 | this.rotateRadians(goog.math.toRadians(degrees), opt_center); 267 | }; 268 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/math.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.math { 2 | 3 | /** 4 | * Returns a random integer greater than or equal to 0 and less than {@code a}. 5 | * @param {number} a The upper bound for the random integer (exclusive). 6 | * @return {number} A random integer N such that 0 <= N < a. 7 | */ 8 | export function randomInt(a: number): number; 9 | 10 | /** 11 | * Returns a random number greater than or equal to {@code a} and less than 12 | * {@code b}. 13 | * @param {number} a The lower bound for the random number (inclusive). 14 | * @param {number} b The upper bound for the random number (exclusive). 15 | * @return {number} A random number N such that a <= N < b. 16 | */ 17 | export function uniformRandom(a: number, b: number): number; 18 | 19 | /** 20 | * Takes a number and clamps it to within the provided bounds. 21 | * @param {number} value The input number. 22 | * @param {number} min The minimum value to return. 23 | * @param {number} max The maximum value to return. 24 | * @return {number} The input number if it is within bounds, or the nearest 25 | * number within the bounds. 26 | */ 27 | export function clamp(value: number, min: number, max: number): number; 28 | 29 | /** 30 | * The % operator in JavaScript returns the remainder of a / b, but differs from 31 | * some other languages in that the result will have the same sign as the 32 | * dividend. For example, -1 % 8 == -1, whereas in some other languages 33 | * (such as Python) the result would be 7. This function emulates the more 34 | * correct modulo behavior, which is useful for certain applications such as 35 | * calculating an offset index in a circular list. 36 | * 37 | * @param {number} a The dividend. 38 | * @param {number} b The divisor. 39 | * @return {number} a % b where the result is between 0 and b (either 0 <= x < b 40 | * or b < x <= 0, depending on the sign of b). 41 | */ 42 | export function modulo(a: number, b: number): number; 43 | 44 | /** 45 | * Performs linear interpolation between values a and b. Returns the value 46 | * between a and b proportional to x (when x is between 0 and 1. When x is 47 | * outside this range, the return value is a linear extrapolation). 48 | * @param {number} a A number. 49 | * @param {number} b A number. 50 | * @param {number} x The proportion between a and b. 51 | * @return {number} The interpolated value between a and b. 52 | */ 53 | export function lerp(a: number, b: number, x: number): number; 54 | 55 | /** 56 | * Tests whether the two values are equal to each other, within a certain 57 | * tolerance to adjust for floating point errors. 58 | * @param {number} a A number. 59 | * @param {number} b A number. 60 | * @param {number=} opt_tolerance Optional tolerance range. Defaults 61 | * to 0.000001. If specified, should be greater than 0. 62 | * @return {boolean} Whether {@code a} and {@code b} are nearly equal. 63 | */ 64 | export function nearlyEquals(a: number, b: number, opt_tolerance?: number): boolean; 65 | 66 | /** 67 | * Normalizes an angle to be in range [0-360). Angles outside this range will 68 | * be normalized to be the equivalent angle with that range. 69 | * @param {number} angle Angle in degrees. 70 | * @return {number} Standardized angle. 71 | */ 72 | export function standardAngle(angle: number): number; 73 | 74 | /** 75 | * Normalizes an angle to be in range [0-2*PI). Angles outside this range will 76 | * be normalized to be the equivalent angle with that range. 77 | * @param {number} angle Angle in radians. 78 | * @return {number} Standardized angle. 79 | */ 80 | export function standardAngleInRadians(angle: number): number; 81 | 82 | /** 83 | * Converts degrees to radians. 84 | * @param {number} angleDegrees Angle in degrees. 85 | * @return {number} Angle in radians. 86 | */ 87 | export function toRadians(angleDegrees: number): number; 88 | 89 | /** 90 | * Converts radians to degrees. 91 | * @param {number} angleRadians Angle in radians. 92 | * @return {number} Angle in degrees. 93 | */ 94 | export function toDegrees(angleRadians: number): number; 95 | 96 | /** 97 | * For a given angle and radius, finds the X portion of the offset. 98 | * @param {number} degrees Angle in degrees (zero points in +X direction). 99 | * @param {number} radius Radius. 100 | * @return {number} The x-distance for the angle and radius. 101 | */ 102 | export function angleDx(degrees: number, radius: number): number; 103 | 104 | /** 105 | * For a given angle and radius, finds the Y portion of the offset. 106 | * @param {number} degrees Angle in degrees (zero points in +X direction). 107 | * @param {number} radius Radius. 108 | * @return {number} The y-distance for the angle and radius. 109 | */ 110 | export function angleDy(degrees: number, radius: number): number; 111 | 112 | /** 113 | * Computes the angle between two points (x1,y1) and (x2,y2). 114 | * Angle zero points in the +X direction, 90 degrees points in the +Y 115 | * direction (down) and from there we grow clockwise towards 360 degrees. 116 | * @param {number} x1 x of first point. 117 | * @param {number} y1 y of first point. 118 | * @param {number} x2 x of second point. 119 | * @param {number} y2 y of second point. 120 | * @return {number} Standardized angle in degrees of the vector from 121 | * x1,y1 to x2,y2. 122 | */ 123 | export function angle(x1: number, y1: number, x2: number, y2: number): number; 124 | 125 | /** 126 | * Computes the difference between startAngle and endAngle (angles in degrees). 127 | * @param {number} startAngle Start angle in degrees. 128 | * @param {number} endAngle End angle in degrees. 129 | * @return {number} The number of degrees that when added to 130 | * startAngle will result in endAngle. Positive numbers mean that the 131 | * direction is clockwise. Negative numbers indicate a counter-clockwise 132 | * direction. 133 | * The shortest route (clockwise vs counter-clockwise) between the angles 134 | * is used. 135 | * When the difference is 180 degrees, the function returns 180 (not -180) 136 | * angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10. 137 | * angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20. 138 | */ 139 | export function angleDifference(startAngle: number, endAngle: number): number; 140 | 141 | /** 142 | * Returns the sign of a number as per the "sign" or "signum" function. 143 | * @param {number} x The number to take the sign of. 144 | * @return {number} -1 when negative, 1 when positive, 0 when 0. 145 | */ 146 | export function sign(x: number): number; 147 | 148 | /** 149 | * JavaScript implementation of Longest Common Subsequence problem. 150 | * http://en.wikipedia.org/wiki/Longest_common_subsequence 151 | * 152 | * Returns the longest possible array that is subarray of both of given arrays. 153 | * 154 | * @param {Array.} array1 First array of objects. 155 | * @param {Array.} array2 Second array of objects. 156 | * @param {Function=} opt_compareFn Function that acts as a custom comparator 157 | * for the array ojects. Function should return true if objects are equal, 158 | * otherwise false. 159 | * @param {Function=} opt_collectorFn Function used to decide what to return 160 | * as a result subsequence. It accepts 2 arguments: index of common element 161 | * in the first array and index in the second. The default function returns 162 | * element from the first array. 163 | * @return {!Array.} A list of objects that are common to both arrays 164 | * such that there is no common subsequence with size greater than the 165 | * length of the list. 166 | */ 167 | export function longestCommonSubsequence(array1: Array, array2: Array, opt_compareFn?: Function, opt_collectorFn?: Function): Array; 168 | 169 | /** 170 | * Returns the sum of the arguments. 171 | * @param {...number} var_args Numbers to add. 172 | * @return {number} The sum of the arguments (0 if no arguments were provided, 173 | * {@code NaN} if any of the arguments is not a valid number). 174 | */ 175 | export function sum(...var_args: number[]): number; 176 | 177 | /** 178 | * Returns the arithmetic mean of the arguments. 179 | * @param {...number} var_args Numbers to average. 180 | * @return {number} The average of the arguments ({@code NaN} if no arguments 181 | * were provided or any of the arguments is not a valid number). 182 | */ 183 | export function average(...var_args: number[]): number; 184 | 185 | /** 186 | * Returns the unbiased sample variance of the arguments. For a definition, 187 | * see e.g. http://en.wikipedia.org/wiki/Variance 188 | * @param {...number} var_args Number samples to analyze. 189 | * @return {number} The unbiased sample variance of the arguments (0 if fewer 190 | * than two samples were provided, or {@code NaN} if any of the samples is 191 | * not a valid number). 192 | */ 193 | export function sampleVariance(...var_args: number[]): number; 194 | 195 | /** 196 | * Returns the sample standard deviation of the arguments. For a definition of 197 | * sample standard deviation, see e.g. 198 | * http://en.wikipedia.org/wiki/Standard_deviation 199 | * @param {...number} var_args Number samples to analyze. 200 | * @return {number} The sample standard deviation of the arguments (0 if fewer 201 | * than two samples were provided, or {@code NaN} if any of the samples is 202 | * not a valid number). 203 | */ 204 | export function standardDeviation(...var_args: number[]): number; 205 | 206 | /** 207 | * Returns whether the supplied number represents an integer, i.e. that is has 208 | * no fractional component. No range-checking is performed on the number. 209 | * @param {number} num The number to test. 210 | * @return {boolean} Whether {@code num} is an integer. 211 | */ 212 | export function isInt(num: number): boolean; 213 | 214 | /** 215 | * Returns whether the supplied number is finite and not NaN. 216 | * @param {number} num The number to test. 217 | * @return {boolean} Whether {@code num} is a finite number. 218 | */ 219 | export function isFiniteNumber(num: number): boolean; 220 | 221 | /** 222 | * Returns the precise value of floor(log10(num)). 223 | * Simpler implementations didn't work because of floating point rounding 224 | * errors. For example 225 | *
    226 | *
  • Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3. 227 | *
  • Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15. 228 | *
  • Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1. 229 | *
230 | * @param {number} num A floating point number. 231 | * @return {number} Its logarithm to base 10 rounded down to the nearest 232 | * integer if num > 0. -Infinity if num == 0. NaN if num < 0. 233 | */ 234 | export function log10Floor(num: number): number; 235 | 236 | /** 237 | * A tweaked variant of {@code Math.floor} which tolerates if the passed number 238 | * is infinitesimally smaller than the closest integer. It often happens with 239 | * the results of floating point calculations because of the finite precision 240 | * of the intermediate results. For example {@code Math.floor(Math.log(1000) / 241 | * Math.LN10) == 2}, not 3 as one would expect. 242 | * @param {number} num A number. 243 | * @param {number=} opt_epsilon An infinitesimally small positive number, the 244 | * rounding error to tolerate. 245 | * @return {number} The largest integer less than or equal to {@code num}. 246 | */ 247 | export function safeFloor(num: number, opt_epsilon?: number): number; 248 | 249 | /** 250 | * A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for 251 | * details. 252 | * @param {number} num A number. 253 | * @param {number=} opt_epsilon An infinitesimally small positive number, the 254 | * rounding error to tolerate. 255 | * @return {number} The smallest integer greater than or equal to {@code num}. 256 | */ 257 | export function safeCeil(num: number, opt_epsilon?: number): number; 258 | } 259 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/math.js: -------------------------------------------------------------------------------- 1 | // Copyright 2006 The Closure Library Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @fileoverview Additional mathematical functions. 17 | */ 18 | 19 | goog.provide('goog.math'); 20 | 21 | goog.require('goog.array'); 22 | goog.require('goog.asserts'); 23 | 24 | 25 | /** 26 | * Returns a random integer greater than or equal to 0 and less than {@code a}. 27 | * @param {number} a The upper bound for the random integer (exclusive). 28 | * @return {number} A random integer N such that 0 <= N < a. 29 | */ 30 | goog.math.randomInt = function(a) { 31 | return Math.floor(Math.random() * a); 32 | }; 33 | 34 | 35 | /** 36 | * Returns a random number greater than or equal to {@code a} and less than 37 | * {@code b}. 38 | * @param {number} a The lower bound for the random number (inclusive). 39 | * @param {number} b The upper bound for the random number (exclusive). 40 | * @return {number} A random number N such that a <= N < b. 41 | */ 42 | goog.math.uniformRandom = function(a, b) { 43 | return a + Math.random() * (b - a); 44 | }; 45 | 46 | 47 | /** 48 | * Takes a number and clamps it to within the provided bounds. 49 | * @param {number} value The input number. 50 | * @param {number} min The minimum value to return. 51 | * @param {number} max The maximum value to return. 52 | * @return {number} The input number if it is within bounds, or the nearest 53 | * number within the bounds. 54 | */ 55 | goog.math.clamp = function(value, min, max) { 56 | return Math.min(Math.max(value, min), max); 57 | }; 58 | 59 | 60 | /** 61 | * The % operator in JavaScript returns the remainder of a / b, but differs from 62 | * some other languages in that the result will have the same sign as the 63 | * dividend. For example, -1 % 8 == -1, whereas in some other languages 64 | * (such as Python) the result would be 7. This function emulates the more 65 | * correct modulo behavior, which is useful for certain applications such as 66 | * calculating an offset index in a circular list. 67 | * 68 | * @param {number} a The dividend. 69 | * @param {number} b The divisor. 70 | * @return {number} a % b where the result is between 0 and b (either 0 <= x < b 71 | * or b < x <= 0, depending on the sign of b). 72 | */ 73 | goog.math.modulo = function(a, b) { 74 | var r = a % b; 75 | // If r and b differ in sign, add b to wrap the result to the correct sign. 76 | return (r * b < 0) ? r + b : r; 77 | }; 78 | 79 | 80 | /** 81 | * Performs linear interpolation between values a and b. Returns the value 82 | * between a and b proportional to x (when x is between 0 and 1. When x is 83 | * outside this range, the return value is a linear extrapolation). 84 | * @param {number} a A number. 85 | * @param {number} b A number. 86 | * @param {number} x The proportion between a and b. 87 | * @return {number} The interpolated value between a and b. 88 | */ 89 | goog.math.lerp = function(a, b, x) { 90 | return a + x * (b - a); 91 | }; 92 | 93 | 94 | /** 95 | * Tests whether the two values are equal to each other, within a certain 96 | * tolerance to adjust for floating point errors. 97 | * @param {number} a A number. 98 | * @param {number} b A number. 99 | * @param {number=} opt_tolerance Optional tolerance range. Defaults 100 | * to 0.000001. If specified, should be greater than 0. 101 | * @return {boolean} Whether {@code a} and {@code b} are nearly equal. 102 | */ 103 | goog.math.nearlyEquals = function(a, b, opt_tolerance) { 104 | return Math.abs(a - b) <= (opt_tolerance || 0.000001); 105 | }; 106 | 107 | 108 | // TODO(user): Rename to normalizeAngle, retaining old name as deprecated 109 | // alias. 110 | /** 111 | * Normalizes an angle to be in range [0-360). Angles outside this range will 112 | * be normalized to be the equivalent angle with that range. 113 | * @param {number} angle Angle in degrees. 114 | * @return {number} Standardized angle. 115 | */ 116 | goog.math.standardAngle = function(angle) { 117 | return goog.math.modulo(angle, 360); 118 | }; 119 | 120 | 121 | /** 122 | * Normalizes an angle to be in range [0-2*PI). Angles outside this range will 123 | * be normalized to be the equivalent angle with that range. 124 | * @param {number} angle Angle in radians. 125 | * @return {number} Standardized angle. 126 | */ 127 | goog.math.standardAngleInRadians = function(angle) { 128 | return goog.math.modulo(angle, 2 * Math.PI); 129 | }; 130 | 131 | 132 | /** 133 | * Converts degrees to radians. 134 | * @param {number} angleDegrees Angle in degrees. 135 | * @return {number} Angle in radians. 136 | */ 137 | goog.math.toRadians = function(angleDegrees) { 138 | return angleDegrees * Math.PI / 180; 139 | }; 140 | 141 | 142 | /** 143 | * Converts radians to degrees. 144 | * @param {number} angleRadians Angle in radians. 145 | * @return {number} Angle in degrees. 146 | */ 147 | goog.math.toDegrees = function(angleRadians) { 148 | return angleRadians * 180 / Math.PI; 149 | }; 150 | 151 | 152 | /** 153 | * For a given angle and radius, finds the X portion of the offset. 154 | * @param {number} degrees Angle in degrees (zero points in +X direction). 155 | * @param {number} radius Radius. 156 | * @return {number} The x-distance for the angle and radius. 157 | */ 158 | goog.math.angleDx = function(degrees, radius) { 159 | return radius * Math.cos(goog.math.toRadians(degrees)); 160 | }; 161 | 162 | 163 | /** 164 | * For a given angle and radius, finds the Y portion of the offset. 165 | * @param {number} degrees Angle in degrees (zero points in +X direction). 166 | * @param {number} radius Radius. 167 | * @return {number} The y-distance for the angle and radius. 168 | */ 169 | goog.math.angleDy = function(degrees, radius) { 170 | return radius * Math.sin(goog.math.toRadians(degrees)); 171 | }; 172 | 173 | 174 | /** 175 | * Computes the angle between two points (x1,y1) and (x2,y2). 176 | * Angle zero points in the +X direction, 90 degrees points in the +Y 177 | * direction (down) and from there we grow clockwise towards 360 degrees. 178 | * @param {number} x1 x of first point. 179 | * @param {number} y1 y of first point. 180 | * @param {number} x2 x of second point. 181 | * @param {number} y2 y of second point. 182 | * @return {number} Standardized angle in degrees of the vector from 183 | * x1,y1 to x2,y2. 184 | */ 185 | goog.math.angle = function(x1, y1, x2, y2) { 186 | return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1, 187 | x2 - x1))); 188 | }; 189 | 190 | 191 | /** 192 | * Computes the difference between startAngle and endAngle (angles in degrees). 193 | * @param {number} startAngle Start angle in degrees. 194 | * @param {number} endAngle End angle in degrees. 195 | * @return {number} The number of degrees that when added to 196 | * startAngle will result in endAngle. Positive numbers mean that the 197 | * direction is clockwise. Negative numbers indicate a counter-clockwise 198 | * direction. 199 | * The shortest route (clockwise vs counter-clockwise) between the angles 200 | * is used. 201 | * When the difference is 180 degrees, the function returns 180 (not -180) 202 | * angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10. 203 | * angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20. 204 | */ 205 | goog.math.angleDifference = function(startAngle, endAngle) { 206 | var d = goog.math.standardAngle(endAngle) - 207 | goog.math.standardAngle(startAngle); 208 | if (d > 180) { 209 | d = d - 360; 210 | } else if (d <= -180) { 211 | d = 360 + d; 212 | } 213 | return d; 214 | }; 215 | 216 | 217 | /** 218 | * Returns the sign of a number as per the "sign" or "signum" function. 219 | * @param {number} x The number to take the sign of. 220 | * @return {number} -1 when negative, 1 when positive, 0 when 0. 221 | */ 222 | goog.math.sign = function(x) { 223 | return x == 0 ? 0 : (x < 0 ? -1 : 1); 224 | }; 225 | 226 | 227 | /** 228 | * JavaScript implementation of Longest Common Subsequence problem. 229 | * http://en.wikipedia.org/wiki/Longest_common_subsequence 230 | * 231 | * Returns the longest possible array that is subarray of both of given arrays. 232 | * 233 | * @param {Array.} array1 First array of objects. 234 | * @param {Array.} array2 Second array of objects. 235 | * @param {Function=} opt_compareFn Function that acts as a custom comparator 236 | * for the array ojects. Function should return true if objects are equal, 237 | * otherwise false. 238 | * @param {Function=} opt_collectorFn Function used to decide what to return 239 | * as a result subsequence. It accepts 2 arguments: index of common element 240 | * in the first array and index in the second. The default function returns 241 | * element from the first array. 242 | * @return {!Array.} A list of objects that are common to both arrays 243 | * such that there is no common subsequence with size greater than the 244 | * length of the list. 245 | */ 246 | goog.math.longestCommonSubsequence = function( 247 | array1, array2, opt_compareFn, opt_collectorFn) { 248 | 249 | var compare = opt_compareFn || function(a, b) { 250 | return a == b; 251 | }; 252 | 253 | var collect = opt_collectorFn || function(i1, i2) { 254 | return array1[i1]; 255 | }; 256 | 257 | var length1 = array1.length; 258 | var length2 = array2.length; 259 | 260 | var arr = []; 261 | for (var i = 0; i < length1 + 1; i++) { 262 | arr[i] = []; 263 | arr[i][0] = 0; 264 | } 265 | 266 | for (var j = 0; j < length2 + 1; j++) { 267 | arr[0][j] = 0; 268 | } 269 | 270 | for (i = 1; i <= length1; i++) { 271 | for (j = 1; j <= length2; j++) { 272 | if (compare(array1[i - 1], array2[j - 1])) { 273 | arr[i][j] = arr[i - 1][j - 1] + 1; 274 | } else { 275 | arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]); 276 | } 277 | } 278 | } 279 | 280 | // Backtracking 281 | var result = []; 282 | var i = length1, j = length2; 283 | while (i > 0 && j > 0) { 284 | if (compare(array1[i - 1], array2[j - 1])) { 285 | result.unshift(collect(i - 1, j - 1)); 286 | i--; 287 | j--; 288 | } else { 289 | if (arr[i - 1][j] > arr[i][j - 1]) { 290 | i--; 291 | } else { 292 | j--; 293 | } 294 | } 295 | } 296 | 297 | return result; 298 | }; 299 | 300 | 301 | /** 302 | * Returns the sum of the arguments. 303 | * @param {...number} var_args Numbers to add. 304 | * @return {number} The sum of the arguments (0 if no arguments were provided, 305 | * {@code NaN} if any of the arguments is not a valid number). 306 | */ 307 | goog.math.sum = function(var_args) { 308 | return /** @type {number} */ (goog.array.reduce(arguments, 309 | function(sum, value) { 310 | return sum + value; 311 | }, 0)); 312 | }; 313 | 314 | 315 | /** 316 | * Returns the arithmetic mean of the arguments. 317 | * @param {...number} var_args Numbers to average. 318 | * @return {number} The average of the arguments ({@code NaN} if no arguments 319 | * were provided or any of the arguments is not a valid number). 320 | */ 321 | goog.math.average = function(var_args) { 322 | return goog.math.sum.apply(null, arguments) / arguments.length; 323 | }; 324 | 325 | 326 | /** 327 | * Returns the unbiased sample variance of the arguments. For a definition, 328 | * see e.g. http://en.wikipedia.org/wiki/Variance 329 | * @param {...number} var_args Number samples to analyze. 330 | * @return {number} The unbiased sample variance of the arguments (0 if fewer 331 | * than two samples were provided, or {@code NaN} if any of the samples is 332 | * not a valid number). 333 | */ 334 | goog.math.sampleVariance = function(var_args) { 335 | var sampleSize = arguments.length; 336 | if (sampleSize < 2) { 337 | return 0; 338 | } 339 | 340 | var mean = goog.math.average.apply(null, arguments); 341 | var variance = goog.math.sum.apply(null, goog.array.map(arguments, 342 | function(val) { 343 | return Math.pow(val - mean, 2); 344 | })) / (sampleSize - 1); 345 | 346 | return variance; 347 | }; 348 | 349 | 350 | /** 351 | * Returns the sample standard deviation of the arguments. For a definition of 352 | * sample standard deviation, see e.g. 353 | * http://en.wikipedia.org/wiki/Standard_deviation 354 | * @param {...number} var_args Number samples to analyze. 355 | * @return {number} The sample standard deviation of the arguments (0 if fewer 356 | * than two samples were provided, or {@code NaN} if any of the samples is 357 | * not a valid number). 358 | */ 359 | goog.math.standardDeviation = function(var_args) { 360 | return Math.sqrt(goog.math.sampleVariance.apply(null, arguments)); 361 | }; 362 | 363 | 364 | /** 365 | * Returns whether the supplied number represents an integer, i.e. that is has 366 | * no fractional component. No range-checking is performed on the number. 367 | * @param {number} num The number to test. 368 | * @return {boolean} Whether {@code num} is an integer. 369 | */ 370 | goog.math.isInt = function(num) { 371 | return isFinite(num) && num % 1 == 0; 372 | }; 373 | 374 | 375 | /** 376 | * Returns whether the supplied number is finite and not NaN. 377 | * @param {number} num The number to test. 378 | * @return {boolean} Whether {@code num} is a finite number. 379 | */ 380 | goog.math.isFiniteNumber = function(num) { 381 | return isFinite(num) && !isNaN(num); 382 | }; 383 | 384 | 385 | /** 386 | * Returns the precise value of floor(log10(num)). 387 | * Simpler implementations didn't work because of floating point rounding 388 | * errors. For example 389 | *
    390 | *
  • Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3. 391 | *
  • Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15. 392 | *
  • Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1. 393 | *
394 | * @param {number} num A floating point number. 395 | * @return {number} Its logarithm to base 10 rounded down to the nearest 396 | * integer if num > 0. -Infinity if num == 0. NaN if num < 0. 397 | */ 398 | goog.math.log10Floor = function(num) { 399 | if (num > 0) { 400 | var x = Math.round(Math.log(num) * Math.LOG10E); 401 | return x - (parseFloat('1e' + x) > num); 402 | } 403 | return num == 0 ? -Infinity : NaN; 404 | }; 405 | 406 | 407 | /** 408 | * A tweaked variant of {@code Math.floor} which tolerates if the passed number 409 | * is infinitesimally smaller than the closest integer. It often happens with 410 | * the results of floating point calculations because of the finite precision 411 | * of the intermediate results. For example {@code Math.floor(Math.log(1000) / 412 | * Math.LN10) == 2}, not 3 as one would expect. 413 | * @param {number} num A number. 414 | * @param {number=} opt_epsilon An infinitesimally small positive number, the 415 | * rounding error to tolerate. 416 | * @return {number} The largest integer less than or equal to {@code num}. 417 | */ 418 | goog.math.safeFloor = function(num, opt_epsilon) { 419 | goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); 420 | return Math.floor(num + (opt_epsilon || 2e-15)); 421 | }; 422 | 423 | 424 | /** 425 | * A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for 426 | * details. 427 | * @param {number} num A number. 428 | * @param {number=} opt_epsilon An infinitesimally small positive number, the 429 | * rounding error to tolerate. 430 | * @return {number} The smallest integer greater than or equal to {@code num}. 431 | */ 432 | goog.math.safeCeil = function(num, opt_epsilon) { 433 | goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); 434 | return Math.ceil(num - (opt_epsilon || 2e-15)); 435 | }; 436 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/size.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.math { 2 | 3 | /** 4 | * Class for representing sizes consisting of a width and height. Undefined 5 | * width and height support is deprecated and results in compiler warning. 6 | * @param {number} width Width. 7 | * @param {number} height Height. 8 | * @constructor 9 | */ 10 | export class Size { 11 | constructor(width: number, height: number); 12 | 13 | /** 14 | * Compares sizes for equality. 15 | * @param {goog.math.Size} a A Size. 16 | * @param {goog.math.Size} b A Size. 17 | * @return {boolean} True iff the sizes have equal widths and equal 18 | * heights, or if both are null. 19 | */ 20 | static equals(a: goog.math.Size, b: goog.math.Size): boolean; 21 | 22 | /** 23 | * @return {!goog.math.Size} A new copy of the Size. 24 | */ 25 | clone(): goog.math.Size; 26 | 27 | /** 28 | * @return {number} The longer of the two dimensions in the size. 29 | */ 30 | getLongest(): number; 31 | 32 | /** 33 | * @return {number} The shorter of the two dimensions in the size. 34 | */ 35 | getShortest(): number; 36 | 37 | /** 38 | * @return {number} The area of the size (width * height). 39 | */ 40 | area(): number; 41 | 42 | /** 43 | * @return {number} The perimeter of the size (width + height) * 2. 44 | */ 45 | perimeter(): number; 46 | 47 | /** 48 | * @return {number} The ratio of the size's width to its height. 49 | */ 50 | aspectRatio(): number; 51 | 52 | /** 53 | * @return {boolean} True if the size has zero area, false if both dimensions 54 | * are non-zero numbers. 55 | */ 56 | isEmpty(): boolean; 57 | 58 | /** 59 | * Clamps the width and height parameters upward to integer values. 60 | * @return {!goog.math.Size} This size with ceil'd components. 61 | */ 62 | ceil(): goog.math.Size; 63 | 64 | /** 65 | * @param {!goog.math.Size} target The target size. 66 | * @return {boolean} True if this Size is the same size or smaller than the 67 | * target size in both dimensions. 68 | */ 69 | fitsInside(target: goog.math.Size): boolean; 70 | 71 | /** 72 | * Clamps the width and height parameters downward to integer values. 73 | * @return {!goog.math.Size} This size with floored components. 74 | */ 75 | floor(): goog.math.Size; 76 | 77 | /** 78 | * Rounds the width and height parameters to integer values. 79 | * @return {!goog.math.Size} This size with rounded components. 80 | */ 81 | round(): goog.math.Size; 82 | 83 | /** 84 | * Scales this size by the given scale factors. The width and height are scaled 85 | * by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not 86 | * given, then {@code sx} is used for both the width and height. 87 | * @param {number} sx The scale factor to use for the width. 88 | * @param {number=} opt_sy The scale factor to use for the height. 89 | * @return {!goog.math.Size} This Size object after scaling. 90 | */ 91 | scale(sx: number, opt_sy?: number): goog.math.Size; 92 | 93 | /** 94 | * Uniformly scales the size to fit inside the dimensions of a given size. The 95 | * original aspect ratio will be preserved. 96 | * 97 | * This function assumes that both Sizes contain strictly positive dimensions. 98 | * @param {!goog.math.Size} target The target size. 99 | * @return {!goog.math.Size} This Size object, after optional scaling. 100 | */ 101 | scaleToFit(target: goog.math.Size): goog.math.Size; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/closure-library/closure/goog/math/size.js: -------------------------------------------------------------------------------- 1 | // Copyright 2007 The Closure Library Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @fileoverview A utility class for representing two-dimensional sizes. 17 | */ 18 | 19 | 20 | goog.provide('goog.math.Size'); 21 | 22 | 23 | 24 | /** 25 | * Class for representing sizes consisting of a width and height. Undefined 26 | * width and height support is deprecated and results in compiler warning. 27 | * @param {number} width Width. 28 | * @param {number} height Height. 29 | * @constructor 30 | */ 31 | goog.math.Size = function(width, height) { 32 | /** 33 | * Width 34 | * @type {number} 35 | */ 36 | this.width = width; 37 | 38 | /** 39 | * Height 40 | * @type {number} 41 | */ 42 | this.height = height; 43 | }; 44 | 45 | 46 | /** 47 | * Compares sizes for equality. 48 | * @param {goog.math.Size} a A Size. 49 | * @param {goog.math.Size} b A Size. 50 | * @return {boolean} True iff the sizes have equal widths and equal 51 | * heights, or if both are null. 52 | */ 53 | goog.math.Size.equals = function(a, b) { 54 | if (a == b) { 55 | return true; 56 | } 57 | if (!a || !b) { 58 | return false; 59 | } 60 | return a.width == b.width && a.height == b.height; 61 | }; 62 | 63 | 64 | /** 65 | * @return {!goog.math.Size} A new copy of the Size. 66 | */ 67 | goog.math.Size.prototype.clone = function() { 68 | return new goog.math.Size(this.width, this.height); 69 | }; 70 | 71 | 72 | if (goog.DEBUG) { 73 | /** 74 | * Returns a nice string representing size. 75 | * @return {string} In the form (50 x 73). 76 | * @override 77 | */ 78 | goog.math.Size.prototype.toString = function() { 79 | return '(' + this.width + ' x ' + this.height + ')'; 80 | }; 81 | } 82 | 83 | 84 | /** 85 | * @return {number} The longer of the two dimensions in the size. 86 | */ 87 | goog.math.Size.prototype.getLongest = function() { 88 | return Math.max(this.width, this.height); 89 | }; 90 | 91 | 92 | /** 93 | * @return {number} The shorter of the two dimensions in the size. 94 | */ 95 | goog.math.Size.prototype.getShortest = function() { 96 | return Math.min(this.width, this.height); 97 | }; 98 | 99 | 100 | /** 101 | * @return {number} The area of the size (width * height). 102 | */ 103 | goog.math.Size.prototype.area = function() { 104 | return this.width * this.height; 105 | }; 106 | 107 | 108 | /** 109 | * @return {number} The perimeter of the size (width + height) * 2. 110 | */ 111 | goog.math.Size.prototype.perimeter = function() { 112 | return (this.width + this.height) * 2; 113 | }; 114 | 115 | 116 | /** 117 | * @return {number} The ratio of the size's width to its height. 118 | */ 119 | goog.math.Size.prototype.aspectRatio = function() { 120 | return this.width / this.height; 121 | }; 122 | 123 | 124 | /** 125 | * @return {boolean} True if the size has zero area, false if both dimensions 126 | * are non-zero numbers. 127 | */ 128 | goog.math.Size.prototype.isEmpty = function() { 129 | return !this.area(); 130 | }; 131 | 132 | 133 | /** 134 | * Clamps the width and height parameters upward to integer values. 135 | * @return {!goog.math.Size} This size with ceil'd components. 136 | */ 137 | goog.math.Size.prototype.ceil = function() { 138 | this.width = Math.ceil(this.width); 139 | this.height = Math.ceil(this.height); 140 | return this; 141 | }; 142 | 143 | 144 | /** 145 | * @param {!goog.math.Size} target The target size. 146 | * @return {boolean} True if this Size is the same size or smaller than the 147 | * target size in both dimensions. 148 | */ 149 | goog.math.Size.prototype.fitsInside = function(target) { 150 | return this.width <= target.width && this.height <= target.height; 151 | }; 152 | 153 | 154 | /** 155 | * Clamps the width and height parameters downward to integer values. 156 | * @return {!goog.math.Size} This size with floored components. 157 | */ 158 | goog.math.Size.prototype.floor = function() { 159 | this.width = Math.floor(this.width); 160 | this.height = Math.floor(this.height); 161 | return this; 162 | }; 163 | 164 | 165 | /** 166 | * Rounds the width and height parameters to integer values. 167 | * @return {!goog.math.Size} This size with rounded components. 168 | */ 169 | goog.math.Size.prototype.round = function() { 170 | this.width = Math.round(this.width); 171 | this.height = Math.round(this.height); 172 | return this; 173 | }; 174 | 175 | 176 | /** 177 | * Scales this size by the given scale factors. The width and height are scaled 178 | * by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not 179 | * given, then {@code sx} is used for both the width and height. 180 | * @param {number} sx The scale factor to use for the width. 181 | * @param {number=} opt_sy The scale factor to use for the height. 182 | * @return {!goog.math.Size} This Size object after scaling. 183 | */ 184 | goog.math.Size.prototype.scale = function(sx, opt_sy) { 185 | var sy = goog.isNumber(opt_sy) ? opt_sy : sx; 186 | this.width *= sx; 187 | this.height *= sy; 188 | return this; 189 | }; 190 | 191 | 192 | /** 193 | * Uniformly scales the size to fit inside the dimensions of a given size. The 194 | * original aspect ratio will be preserved. 195 | * 196 | * This function assumes that both Sizes contain strictly positive dimensions. 197 | * @param {!goog.math.Size} target The target size. 198 | * @return {!goog.math.Size} This Size object, after optional scaling. 199 | */ 200 | goog.math.Size.prototype.scaleToFit = function(target) { 201 | var s = this.aspectRatio() > target.aspectRatio() ? 202 | target.width / this.width : 203 | target.height / this.height; 204 | 205 | return this.scale(s); 206 | }; 207 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Load all type definition files. 2 | /// 3 | function register() { 4 | require('./closure-library/closure/goog/bootstrap/nodejs'); 5 | } 6 | exports.register = register; 7 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | // Load all type definition files. 2 | /// 3 | 4 | // Install closure-library bootstrap for node.js. 5 | declare function require(name: string): any; 6 | 7 | export function register() { 8 | require('./closure-library/closure/goog/bootstrap/nodejs'); 9 | } 10 | -------------------------------------------------------------------------------- /misc/error.log: -------------------------------------------------------------------------------- 1 | closure-library.d.ts/closure/goog/datasource/fastdatanode.d.ts(223,9): error TS2416: Property 'setChildNode' in type 'PrimitiveFastDataNode' is not assignable to the same property in base type 'AbstractFastDataNode'. 2 | Type '(name: string, value: Object) => void' is not assignable to type '(name: string, value: Object) => Object'. 3 | Type 'void' is not assignable to type 'Object'. 4 | closure-library.d.ts/closure/goog/debug/error.d.ts(13,11): error TS2506: 'Error' is referenced directly or indirectly in its own base expression. 5 | closure-library.d.ts/closure/goog/dom/dom.d.ts(81,106): error TS2304: Cannot find name 'R'. 6 | closure-library.d.ts/closure/goog/dom/dom.d.ts(103,138): error TS2304: Cannot find name 'R'. 7 | closure-library.d.ts/closure/goog/dom/dom.d.ts(117,126): error TS2304: Cannot find name 'R'. 8 | closure-library.d.ts/closure/goog/dom/dom.d.ts(165,103): error TS2304: Cannot find name 'R'. 9 | closure-library.d.ts/closure/goog/dom/dom.d.ts(219,149): error TS2304: Cannot find name 'R'. 10 | closure-library.d.ts/closure/goog/dom/dom.d.ts(238,144): error TS2304: Cannot find name 'R'. 11 | closure-library.d.ts/closure/goog/dom/dom.d.ts(249,61): error TS2304: Cannot find name 'R'. 12 | closure-library.d.ts/closure/goog/dom/dom.d.ts(666,144): error TS2304: Cannot find name 'R'. 13 | closure-library.d.ts/closure/goog/dom/dom.d.ts(761,111): error TS2304: Cannot find name 'R'. 14 | closure-library.d.ts/closure/goog/dom/dom.d.ts(793,143): error TS2304: Cannot find name 'R'. 15 | closure-library.d.ts/closure/goog/dom/dom.d.ts(807,131): error TS2304: Cannot find name 'R'. 16 | closure-library.d.ts/closure/goog/dom/dom.d.ts(854,108): error TS2304: Cannot find name 'R'. 17 | closure-library.d.ts/closure/goog/dom/dom.d.ts(1022,173): error TS2304: Cannot find name 'R'. 18 | closure-library.d.ts/closure/goog/dom/dom.d.ts(1041,168): error TS2304: Cannot find name 'R'. 19 | closure-library.d.ts/closure/goog/dom/dom.d.ts(1052,66): error TS2304: Cannot find name 'R'. 20 | closure-library.d.ts/closure/goog/dom/dom.d.ts(1493,149): error TS2304: Cannot find name 'R'. 21 | closure-library.d.ts/closure/goog/events/keycodes.d.ts(15,10): error TS2300: Duplicate identifier 'KeyCodes'. 22 | closure-library.d.ts/closure/goog/events/keycodes.d.ts(16,9): error TS2300: Duplicate identifier 'KeyCodes'. 23 | closure-library.d.ts/closure/goog/events/keycodes.d.ts(140,28): error TS2300: Duplicate identifier 'KeyCodes'. 24 | closure-library.d.ts/closure/goog/graphics/canvasgraphics.d.ts(265,9): error TS2416: Property 'getTextWidth' in type 'CanvasGraphics' is not assignable to the same property in base type 'AbstractGraphics'. 25 | Type '(text: string, font: Font) => void' is not assignable to type '(text: string, font: Font) => number'. 26 | Type 'void' is not assignable to type 'number'. 27 | closure-library.d.ts/closure/goog/html/sanitizer/htmlsanitizer.d.ts(58,53): error TS2339: Property 'SafeDomTreeProcessor' does not exist on type 'typeof sanitizer'. 28 | closure-library.d.ts/closure/goog/i18n/datetimesymbols.d.ts(760,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'DateTimeSymbols' must be of type 'DateTimeSymbolsType', but here has type 'any'. 29 | closure-library.d.ts/closure/goog/i18n/ordinalrules.d.ts(24,9): error TS2300: Duplicate identifier 'select'. 30 | closure-library.d.ts/closure/goog/i18n/ordinalrules.d.ts(35,14): error TS2300: Duplicate identifier 'select'. 31 | closure-library.d.ts/closure/goog/i18n/pluralrules.d.ts(24,9): error TS2300: Duplicate identifier 'select'. 32 | closure-library.d.ts/closure/goog/i18n/pluralrules.d.ts(35,14): error TS2300: Duplicate identifier 'select'. 33 | closure-library.d.ts/closure/goog/labs/net/webchannel.d.ts(19,15): error TS2320: Interface 'WebChannel' cannot simultaneously extend types 'EventTarget' and 'Listenable'. 34 | Named property 'dispatchEvent' of types 'EventTarget' and 'Listenable' are not identical. 35 | closure-library.d.ts/closure/goog/labs/testing/environment.d.ts(42,9): error TS2300: Duplicate identifier 'Environment'. 36 | closure-library.d.ts/closure/goog/labs/testing/environment.d.ts(45,34): error TS2300: Duplicate identifier 'Environment'. 37 | closure-library.d.ts/closure/goog/net/browserchannel.d.ts(76,16): error TS2300: Duplicate identifier 'Event'. 38 | closure-library.d.ts/closure/goog/net/browserchannel.d.ts(424,51): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 39 | closure-library.d.ts/closure/goog/net/browserchannel.d.ts(768,40): error TS2300: Duplicate identifier 'Event'. 40 | closure-library.d.ts/closure/goog/net/browsertestchannel.d.ts(46,51): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 41 | closure-library.d.ts/closure/goog/net/errorcode.d.ts(11,10): error TS2300: Duplicate identifier 'ErrorCode'. 42 | closure-library.d.ts/closure/goog/net/errorcode.d.ts(12,9): error TS2300: Duplicate identifier 'ErrorCode'. 43 | closure-library.d.ts/closure/goog/net/errorcode.d.ts(26,25): error TS2300: Duplicate identifier 'ErrorCode'. 44 | closure-library.d.ts/closure/goog/net/httpstatus.d.ts(14,10): error TS2300: Duplicate identifier 'HttpStatus'. 45 | closure-library.d.ts/closure/goog/net/httpstatus.d.ts(15,9): error TS2300: Duplicate identifier 'HttpStatus'. 46 | closure-library.d.ts/closure/goog/net/httpstatus.d.ts(69,25): error TS2300: Duplicate identifier 'HttpStatus'. 47 | closure-library.d.ts/closure/goog/net/streams/streamfactory.d.ts(33,56): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 48 | closure-library.d.ts/closure/goog/net/streams/xhrnodereadablestream.d.ts(19,49): error TS2694: Namespace 'goog.net.streams' has no exported member 'XhrStreamReader'. 49 | closure-library.d.ts/closure/goog/net/xhriopool.d.ts(26,34): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 50 | closure-library.d.ts/closure/goog/net/xhrmanager.d.ts(76,283): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 51 | closure-library.d.ts/closure/goog/net/xhrmanager.d.ts(103,104): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 52 | closure-library.d.ts/closure/goog/net/xhrmanager.d.ts(131,283): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 53 | closure-library.d.ts/closure/goog/net/xhrmanager.d.ts(231,37): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 54 | closure-library.d.ts/closure/goog/positioning/positioning.d.ts(71,10): error TS2300: Duplicate identifier 'OverflowStatus'. 55 | closure-library.d.ts/closure/goog/positioning/positioning.d.ts(72,9): error TS2300: Duplicate identifier 'OverflowStatus'. 56 | closure-library.d.ts/closure/goog/positioning/positioning.d.ts(217,33): error TS2300: Duplicate identifier 'OverflowStatus'. 57 | closure-library.d.ts/closure/goog/promise/promise.d.ts(83,51): error TS2304: Cannot find name 'RESULT'. 58 | closure-library.d.ts/closure/goog/promise/thenable.d.ts(59,117): error TS2304: Cannot find name 'THIS'. 59 | closure-library.d.ts/closure/goog/promise/thenable.d.ts(59,124): error TS2304: Cannot find name 'RESULT'. 60 | closure-library.d.ts/closure/goog/reflect/reflect.d.ts(89,51): error TS2304: Cannot find name 'V'. 61 | closure-library.d.ts/closure/goog/reflect/reflect.d.ts(89,89): error TS2304: Cannot find name 'V'. 62 | closure-library.d.ts/closure/goog/reflect/reflect.d.ts(89,123): error TS2304: Cannot find name 'V'. 63 | closure-library.d.ts/closure/goog/testing/events/events.d.ts(20,11): error TS2506: 'Event' is referenced directly or indirectly in its own base expression. 64 | closure-library.d.ts/closure/goog/testing/net/xhrio.d.ts(15,34): error TS2339: Property 'XhrIo' does not exist on type 'typeof net'. 65 | closure-library.d.ts/closure/goog/testing/net/xhrio.d.ts(97,40): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 66 | closure-library.d.ts/closure/goog/testing/net/xhrio.d.ts(104,37): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 67 | closure-library.d.ts/closure/goog/testing/net/xhrio.d.ts(398,43): error TS2339: Property 'XhrIo' does not exist on type 'typeof net'. 68 | closure-library.d.ts/closure/goog/testing/net/xhrio.d.ts(398,43): error TS2694: Namespace 'goog.net' has no exported member 'XhrIo'. 69 | closure-library.d.ts/closure/goog/testing/recordfunction.d.ts(113,76): error TS2694: Namespace 'goog.testing.recordFunction' has no exported member 'Type'. 70 | closure-library.d.ts/closure/goog/testing/testsuite.d.ts(18,82): error TS2304: Cannot find name 'TestSuiteOptions'. 71 | closure-library.d.ts/closure/goog/ui/animatedzippy.d.ts(23,146): error TS2315: Type 'Role' is not generic. 72 | closure-library.d.ts/closure/goog/ui/checkbox.d.ts(21,11): error TS2417: Class static side 'typeof Checkbox' incorrectly extends base class static side 'typeof Control'. 73 | Types of property 'State' are incompatible. 74 | Type '{ CHECKED: boolean; UNCHECKED: boolean; UNDETERMINED: boolean; }' is not assignable to type '{ ALL: number; DISABLED: number; HOVER: number; ACTIVE: number; SELECTED: number; CHECKED: number; FOCUSED: number; OPENED: number; }'. 75 | Property 'ALL' is missing in type '{ CHECKED: boolean; UNCHECKED: boolean; UNDETERMINED: boolean; }'. 76 | closure-library.d.ts/closure/goog/ui/colormenubuttonrenderer.d.ts(12,11): error TS2417: Class static side 'typeof ColorMenuButtonRenderer' incorrectly extends base class static side 'typeof MenuButtonRenderer'. 77 | Types of property 'wrapCaption' are incompatible. 78 | Type '(content: ControlContent, dom: DomHelper) => Element' is not assignable to type '(content: ControlContent, cssClass: string, dom: DomHelper) => Element'. 79 | Types of parameters 'dom' and 'cssClass' are incompatible. 80 | Type 'string' is not assignable to type 'DomHelper'. 81 | closure-library.d.ts/closure/goog/ui/colorpicker.d.ts(18,11): error TS2417: Class static side 'typeof ColorPicker' incorrectly extends base class static side 'typeof Component'. 82 | Types of property 'EventType' are incompatible. 83 | Type '{ CHANGE: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 84 | Property 'BEFORE_SHOW' is missing in type '{ CHANGE: string; }'. 85 | closure-library.d.ts/closure/goog/ui/container.d.ts(28,11): error TS2417: Class static side 'typeof Container' incorrectly extends base class static side 'typeof Component'. 86 | Types of property 'EventType' are incompatible. 87 | Type '{ AFTER_SHOW: string; AFTER_HIDE: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 88 | Property 'BEFORE_SHOW' is missing in type '{ AFTER_SHOW: string; AFTER_HIDE: string; }'. 89 | closure-library.d.ts/closure/goog/ui/dialog.d.ts(44,11): error TS2417: Class static side 'typeof Dialog' incorrectly extends base class static side 'typeof ModalPopup'. 90 | Types of property 'EventType' are incompatible. 91 | Type '{ SELECT: string; AFTER_HIDE: string; AFTER_SHOW: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 92 | Property 'BEFORE_SHOW' is missing in type '{ SELECT: string; AFTER_HIDE: string; AFTER_SHOW: string; }'. 93 | closure-library.d.ts/closure/goog/ui/editor/linkdialog.d.ts(19,11): error TS2417: Class static side 'typeof LinkDialog' incorrectly extends base class static side 'typeof AbstractDialog'. 94 | Types of property 'EventType' are incompatible. 95 | Type '{ BEFORE_TEST_LINK: string; }' is not assignable to type '{ AFTER_HIDE: string; CANCEL: string; OK: string; }'. 96 | Property 'AFTER_HIDE' is missing in type '{ BEFORE_TEST_LINK: string; }'. 97 | closure-library.d.ts/closure/goog/ui/filteredmenu.d.ts(15,11): error TS2417: Class static side 'typeof FilteredMenu' incorrectly extends base class static side 'typeof Menu'. 98 | Types of property 'EventType' are incompatible. 99 | Type '{ FILTER_CHANGED: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; BEFORE_HIDE: string; HIDE: string; }'. 100 | Property 'BEFORE_SHOW' is missing in type '{ FILTER_CHANGED: string; }'. 101 | closure-library.d.ts/closure/goog/ui/menu.d.ts(16,11): error TS2417: Class static side 'typeof Menu' incorrectly extends base class static side 'typeof Container'. 102 | Types of property 'EventType' are incompatible. 103 | Type '{ BEFORE_SHOW: string; SHOW: string; BEFORE_HIDE: string; HIDE: string; }' is not assignable to type '{ AFTER_SHOW: string; AFTER_HIDE: string; }'. 104 | Property 'AFTER_SHOW' is missing in type '{ BEFORE_SHOW: string; SHOW: string; BEFORE_HIDE: string; HIDE: string; }'. 105 | closure-library.d.ts/closure/goog/ui/menu.d.ts(161,9): error TS2416: Property 'setVisible' in type 'Menu' is not assignable to the same property in base type 'Container'. 106 | Type '(show: boolean, opt_force?: boolean, opt_e?: Event) => void' is not assignable to type '(visible: boolean, opt_force?: boolean) => boolean'. 107 | Type 'void' is not assignable to type 'boolean'. 108 | closure-library.d.ts/closure/goog/ui/menubase.d.ts(23,16): error TS2300: Duplicate identifier 'Events'. 109 | closure-library.d.ts/closure/goog/ui/menubase.d.ts(91,33): error TS2300: Duplicate identifier 'Events'. 110 | closure-library.d.ts/closure/goog/ui/palette.d.ts(26,11): error TS2417: Class static side 'typeof Palette' incorrectly extends base class static side 'typeof Control'. 111 | Types of property 'EventType' are incompatible. 112 | Type '{ AFTER_HIGHLIGHT: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 113 | Property 'BEFORE_SHOW' is missing in type '{ AFTER_HIGHLIGHT: string; }'. 114 | closure-library.d.ts/closure/goog/ui/paletterenderer.d.ts(110,9): error TS2416: Property 'decorate' in type 'PaletteRenderer' is not assignable to the same property in base type 'ControlRenderer'. 115 | Type '(palette: Control, element: Element) => void' is not assignable to type '(control: Control, element: Element) => Element'. 116 | Type 'void' is not assignable to type 'Element'. 117 | closure-library.d.ts/closure/goog/ui/ratings.d.ts(15,11): error TS2417: Class static side 'typeof Ratings' incorrectly extends base class static side 'typeof Component'. 118 | Types of property 'EventType' are incompatible. 119 | Type '{ CHANGE: string; HIGHLIGHT_CHANGE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 120 | Property 'BEFORE_SHOW' is missing in type '{ CHANGE: string; HIGHLIGHT_CHANGE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; }'. 121 | closure-library.d.ts/closure/goog/ui/scrollfloater.d.ts(20,11): error TS2417: Class static side 'typeof ScrollFloater' incorrectly extends base class static side 'typeof Component'. 122 | Types of property 'EventType' are incompatible. 123 | Type '{ FLOAT: string; DOCK: string; PIN: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 124 | Property 'BEFORE_SHOW' is missing in type '{ FLOAT: string; DOCK: string; PIN: string; }'. 125 | closure-library.d.ts/closure/goog/ui/sliderbase.d.ts(16,11): error TS2417: Class static side 'typeof SliderBase' incorrectly extends base class static side 'typeof Component'. 126 | Types of property 'EventType' are incompatible. 127 | Type '{ DRAG_VALUE_START: string; DRAG_VALUE_END: string; DRAG_EXTENT_START: string; DRAG_EXTENT_END: string; DRAG_START: string; DRAG_END: string; ANIMATION_END: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 128 | Property 'BEFORE_SHOW' is missing in type '{ DRAG_VALUE_START: string; DRAG_VALUE_END: string; DRAG_EXTENT_START: string; DRAG_EXTENT_END: string; DRAG_START: string; DRAG_END: string; ANIMATION_END: string; }'. 129 | closure-library.d.ts/closure/goog/ui/splitpane.d.ts(23,11): error TS2417: Class static side 'typeof SplitPane' incorrectly extends base class static side 'typeof Component'. 130 | Types of property 'EventType' are incompatible. 131 | Type '{ HANDLE_DRAG: string; HANDLE_DRAG_END: string; HANDLE_SNAP: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 132 | Property 'BEFORE_SHOW' is missing in type '{ HANDLE_DRAG: string; HANDLE_DRAG_END: string; HANDLE_SNAP: string; }'. 133 | closure-library.d.ts/closure/goog/ui/tablesorter.d.ts(21,11): error TS2417: Class static side 'typeof TableSorter' incorrectly extends base class static side 'typeof Component'. 134 | Types of property 'EventType' are incompatible. 135 | Type '{ BEFORESORT: string; SORT: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 136 | Property 'BEFORE_SHOW' is missing in type '{ BEFORESORT: string; SORT: string; }'. 137 | closure-library.d.ts/closure/goog/ui/textarea.d.ts(19,11): error TS2417: Class static side 'typeof Textarea' incorrectly extends base class static side 'typeof Control'. 138 | Types of property 'EventType' are incompatible. 139 | Type '{ RESIZE: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 140 | Property 'BEFORE_SHOW' is missing in type '{ RESIZE: string; }'. 141 | closure-library.d.ts/closure/goog/ui/tree/basenode.d.ts(20,11): error TS2417: Class static side 'typeof BaseNode' incorrectly extends base class static side 'typeof Component'. 142 | Types of property 'EventType' are incompatible. 143 | Type '{ BEFORE_EXPAND: string; EXPAND: string; BEFORE_COLLAPSE: string; COLLAPSE: string; }' is not assignable to type '{ BEFORE_SHOW: string; SHOW: string; HIDE: string; DISABLE: string; ENABLE: string; HIGHLIGHT: string; UNHIGHLIGHT: string; ACTIVATE: string; DEACTIVATE: string; SELECT: string; UNSELECT: string; ... 9 more ...; CHANGE: string; }'. 144 | Property 'BEFORE_SHOW' is missing in type '{ BEFORE_EXPAND: string; EXPAND: string; BEFORE_COLLAPSE: string; COLLAPSE: string; }'. 145 | closure-library.d.ts/closure/goog/ui/zippy.d.ts(30,204): error TS2315: Type 'Role' is not generic. 146 | -------------------------------------------------------------------------------- /misc/goog.module.get.txt: -------------------------------------------------------------------------------- 1 | ./closure-library/closure/goog/labs/net/webchannel/webchannelbase.js 2 | ./closure-library/closure/goog/net/streams/jsonstreamparser.js 3 | ./closure-library/closure/goog/net/streams/xhrstreamreader.js 4 | -------------------------------------------------------------------------------- /misc/goog.module.txt: -------------------------------------------------------------------------------- 1 | ./closure-library/closure/goog/delegate/delegateregistry.js 2 | ./closure-library/closure/goog/delegate/delegates.js 3 | ./closure-library/closure/goog/dom/uri.js 4 | ./closure-library/closure/goog/html/cssspecificity.js 5 | ./closure-library/closure/goog/html/sanitizer/csspropertysanitizer.js 6 | ./closure-library/closure/goog/html/sanitizer/elementweakmap.js 7 | ./closure-library/closure/goog/html/sanitizer/noclobber.js 8 | ./closure-library/closure/goog/html/sanitizer/safedomtreeprocessor.js 9 | ./closure-library/closure/goog/i18n/dateintervalformat.js 10 | ./closure-library/closure/goog/i18n/dateintervalpatterns.js 11 | ./closure-library/closure/goog/i18n/dateintervalpatternsext.js 12 | ./closure-library/closure/goog/i18n/dateintervalsymbols.js 13 | ./closure-library/closure/goog/i18n/dateintervalsymbolsext.js 14 | ./closure-library/closure/goog/iter/es6.js 15 | ./closure-library/closure/goog/labs/iterable/iterable.js 16 | ./closure-library/closure/goog/labs/net/webchannel/environment.js 17 | ./closure-library/closure/goog/labs/net/webchannel/forwardchannelrequestpool.js 18 | ./closure-library/closure/goog/loader/activemodulemanager.js 19 | ./closure-library/closure/goog/net/rpc/httpcors.js 20 | ./closure-library/closure/goog/net/streams/base64pbstreamparser.js 21 | ./closure-library/closure/goog/net/streams/pbjsonstreamparser.js 22 | ./closure-library/closure/goog/net/streams/utils.js 23 | ./closure-library/closure/goog/promise/nativeresolver.js 24 | ./closure-library/closure/goog/structs/avltree.js 25 | ./closure-library/closure/goog/test_module.js 26 | ./closure-library/closure/goog/test_module_dep.js 27 | ./closure-library/closure/goog/testing/assertionfailure.js 28 | ./closure-library/closure/goog/testing/parallel_closure_test_suite.js 29 | -------------------------------------------------------------------------------- /misc/goog.scope.txt: -------------------------------------------------------------------------------- 1 | ./closure-library/closure/goog/events/browserfeature.js 2 | ./closure-library/closure/goog/labs/net/webchannel/basetestchannel.js 3 | ./closure-library/closure/goog/labs/net/webchannel/channel.js 4 | ./closure-library/closure/goog/labs/net/webchannel/channelrequest.js 5 | ./closure-library/closure/goog/labs/net/webchannel/netutils.js 6 | ./closure-library/closure/goog/labs/net/webchannel/requeststats.js 7 | ./closure-library/closure/goog/labs/net/webchannel/webchannelbase.js 8 | ./closure-library/closure/goog/labs/net/webchannel/webchannelbasetransport.js 9 | ./closure-library/closure/goog/labs/net/webchannel/webchanneldebug.js 10 | ./closure-library/closure/goog/labs/net/webchannel/wire.js 11 | ./closure-library/closure/goog/labs/net/webchannel/wirev8.js 12 | ./closure-library/closure/goog/labs/net/xhr.js 13 | ./closure-library/closure/goog/labs/useragent/test_agents.js 14 | ./closure-library/closure/goog/net/streams/base64streamdecoder.js 15 | ./closure-library/closure/goog/net/streams/jsonstreamparser.js 16 | ./closure-library/closure/goog/net/streams/pbstreamparser.js 17 | ./closure-library/closure/goog/net/streams/xhrstreamreader.js 18 | ./closure-library/closure/goog/net/xhrio.js 19 | ./closure-library/closure/goog/net/xpc/directtransport.js 20 | ./closure-library/closure/goog/ui/bubble.js 21 | -------------------------------------------------------------------------------- /misc/ignore.txt: -------------------------------------------------------------------------------- 1 | ./closure-library/closure/goog/goog.js 2 | ./closure-library/closure/goog/i18n/compactnumberformatsymbolsext.js 3 | ./closure-library/closure/goog/i18n/datetimepatternsext.js 4 | ./closure-library/closure/goog/i18n/datetimesymbolsext.js 5 | ./closure-library/closure/goog/i18n/numberformatsymbolsext.js 6 | ./closure-library/closure/goog/module/module.js 7 | ./closure-library/closure/goog/proto2/package_test.pb.js 8 | ./closure-library/closure/goog/proto2/test.pb.js 9 | ./closure-library/closure/goog/soy/soy_testhelper.js 10 | ./closure-library/closure/goog/storage/mechanism/mechanismtestdefinition.js 11 | ./closure-library/closure/goog/transpile.js 12 | ./closure-library/closure/goog/tweak/testhelpers.js 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "closure-ts", 3 | "description": "Generate TypeScript declarations(d.ts) of Closure Library", 4 | "version": "0.3.0", 5 | "author": "Teppei Sato ", 6 | "engines": { 7 | "node": ">=8" 8 | }, 9 | "main": "lib/generator.js", 10 | "bin": { 11 | "closurets": "./bin/closurets.js" 12 | }, 13 | "files": [ 14 | "index.js", 15 | "bin", 16 | "lib" 17 | ], 18 | "scripts": { 19 | "tsc": "tsc", 20 | "clean": "rimraf lib", 21 | "build": "run-s clean tsc", 22 | "lint:js": "eslint bin test", 23 | "lint:ts": "tslint -c tslint.js src/*.ts", 24 | "mocha": "mocha test --color", 25 | "test": "npm-run-all --aggregate-output -p lint:ts build -p lint:js mocha" 26 | }, 27 | "dependencies": { 28 | "@teppeis/doctrine": "^3.1.0", 29 | "cli-color": "^1.4.0", 30 | "commander": "^2.6.0", 31 | "deep-equal": "^1.0.0", 32 | "esprima": "^4.0.1", 33 | "espurify": "^1.0.0", 34 | "estraverse": "^4.2.0", 35 | "lodash": "^4.17.11", 36 | "mkdirp": "^0.5.0" 37 | }, 38 | "devDependencies": { 39 | "@types/cli-color": "^0.3.29", 40 | "@types/deep-equal": "^1.0.1", 41 | "@types/estree": "0.0.39", 42 | "@types/lodash": "^4.14.118", 43 | "@types/mkdirp": "^0.5.2", 44 | "@types/node": "^10.12.9", 45 | "diff": "^3.5.0", 46 | "eslint": "^5.9.0", 47 | "eslint-config-teppeis": "^8.3.1", 48 | "mocha": "^5.2.0", 49 | "npm-run-all": "^4.1.3", 50 | "prettier": "^1.15.2", 51 | "rimraf": "^2.6.2", 52 | "tslint": "^5.11.0", 53 | "tslint-eslint-rules": "^5.4.0", 54 | "tslint-import-eslint-config": "^1.0.2", 55 | "tslint-plugin-prettier": "^2.0.1", 56 | "typescript": "^3.1.6" 57 | }, 58 | "repository": "teppeis/closure-ts", 59 | "keywords": [ 60 | "closure", 61 | "jsdoc", 62 | "typescript" 63 | ], 64 | "license": "MIT" 65 | } 66 | -------------------------------------------------------------------------------- /src/cli.ts: -------------------------------------------------------------------------------- 1 | import clc from 'cli-color'; 2 | import commander from 'commander'; 3 | import fs from 'fs'; 4 | import mkdirp from 'mkdirp'; 5 | import path from 'path'; 6 | import {generate} from './generator'; 7 | 8 | class Logger { 9 | private color_: boolean; 10 | private messages_: string[]; 11 | private stdout: NodeJS.WritableStream; 12 | private stderr: NodeJS.WritableStream; 13 | 14 | constructor(enableColor: boolean, stdout: NodeJS.WritableStream, stderr: NodeJS.WritableStream) { 15 | this.color_ = !!enableColor; 16 | this.messages_ = []; 17 | this.stdout = stdout; 18 | this.stderr = stderr; 19 | } 20 | 21 | raw(msg: string) { 22 | this.messages_.push(msg); 23 | } 24 | 25 | info(msg: string) { 26 | this.messages_.push(msg); 27 | } 28 | 29 | warn(msg: string) { 30 | this.messages_.push(this.color_ ? clc.yellow(msg) : msg); 31 | } 32 | 33 | error(msg: string) { 34 | this.messages_.push(this.color_ ? clc.red(msg) : msg); 35 | } 36 | 37 | success(msg: string) { 38 | this.messages_.push(this.color_ ? clc.green(msg) : msg); 39 | } 40 | 41 | items(items: string[]) { 42 | if (items.length === 0) { 43 | items = ['(none)']; 44 | } 45 | this.messages_ = this.messages_.concat( 46 | items.map(item => { 47 | item = `- ${item}`; 48 | return this.color_ ? clc.blackBright(item) : item; 49 | }, this) 50 | ); 51 | } 52 | 53 | flush(success: boolean) { 54 | const out = success ? this.stdout : this.stderr; 55 | this.messages_.forEach(msg => { 56 | out.write(`${msg}\n`); 57 | }); 58 | this.empty(); 59 | } 60 | 61 | empty() { 62 | this.messages_ = []; 63 | } 64 | } 65 | 66 | function setCommandOptions(command: commander.Command) { 67 | return command 68 | .version(require('../package.json').version, '-v, --version') 69 | .usage('[options] files...') 70 | .option('--no-color', 'Disable color highlight.'); 71 | } 72 | 73 | export default function main( 74 | argv: string[], 75 | stdout: NodeJS.WritableStream, 76 | stderr: NodeJS.WritableStream, 77 | exit: (code?: number) => never 78 | ) { 79 | const program = new commander.Command(); 80 | setCommandOptions(program).parse(argv); 81 | 82 | if (program.args.length < 1) { 83 | program.outputHelp(); 84 | exit(1); 85 | } 86 | 87 | const log = new Logger(program.color, stdout, stderr); 88 | 89 | program.args.forEach(file => { 90 | log.warn(`File: ${file}\n`); 91 | const code = fs.readFileSync(file, 'utf8'); 92 | try { 93 | const generated = generate(code); 94 | if (generated) { 95 | const relativePath = path.relative(`${__dirname}/../closure-library`, file); 96 | const filepath = path 97 | .join(`${__dirname}/../closure-library.d.ts`, relativePath) 98 | .replace(/\.js$/, '.d.ts'); 99 | mkdirp.sync(path.dirname(filepath)); 100 | fs.writeFileSync(filepath, generated); 101 | } 102 | } catch (e) { 103 | console.error(file, e); 104 | } 105 | }); 106 | } 107 | -------------------------------------------------------------------------------- /src/generator.ts: -------------------------------------------------------------------------------- 1 | import doctrine from '@teppeis/doctrine'; 2 | import {parseScript} from 'esprima'; 3 | import estraverse from 'estraverse'; 4 | import * as estree from 'estree'; 5 | import deepEqual from 'deep-equal'; 6 | import espurify from 'espurify'; 7 | import printer from './printer'; 8 | import * as util from './util'; 9 | import {ClassInfo, EnumInfo, FunctionInfo, ModuleInfo, TypeDefInfo, VarInfo} from './types'; 10 | 11 | const Syntax = estraverse.Syntax; 12 | 13 | export function generate(code: string): string { 14 | const ast = parseScript(code, { 15 | comment: true, 16 | attachComment: true, 17 | loc: true, 18 | }); 19 | const declarations: Record = {}; 20 | const provides: string[] = []; 21 | ast.body.forEach(statement => { 22 | try { 23 | parseStatement(statement, declarations, provides); 24 | } catch (e) { 25 | console.error(statement); 26 | throw e; 27 | } 28 | }); 29 | return printer(declarations, provides); 30 | } 31 | 32 | function parseStatement( 33 | statement: estree.Statement | estree.ModuleDeclaration, 34 | declarations: Record, 35 | provides: string[] 36 | ): void { 37 | if (statement.type === Syntax.IfStatement || statement.type === Syntax.TryStatement) { 38 | // TODO: ignore top level IfStatement or TryStatement now. 39 | return; 40 | } 41 | 42 | if (extractProvide(statement, provides)) { 43 | return; 44 | } 45 | 46 | let comments = statement.leadingComments; 47 | if (!comments || !comments.length) { 48 | return; 49 | } 50 | comments = comments.filter( 51 | comment => comment.type === 'Block' && comment.value.charAt(0) === '*' 52 | ); 53 | const comment = comments[comments.length - 1]; 54 | if (!comment) { 55 | return; 56 | } 57 | 58 | const doc = doctrine.parse(comment.value, { 59 | unwrap: true, 60 | tags: [ 61 | 'param', 62 | 'enum', 63 | 'return', 64 | 'private', 65 | 'type', 66 | 'template', 67 | 'typedef', 68 | 'constructor', 69 | 'interface', 70 | 'record', 71 | 'extends', 72 | 'override', 73 | ], 74 | }); 75 | // console.log(doc.tags); 76 | 77 | const typedefTag = getTypedefTag(doc.tags); 78 | let isClass = isClassDeclaration(statement, doc.tags); 79 | let isInterface = isInterfaceDeclaration(statement, doc.tags); 80 | const enumTag = getEnumTag(doc.tags); 81 | if (isPrivate(doc.tags)) { 82 | if (isClass) { 83 | isClass = false; 84 | isInterface = true; 85 | } else if (!typedefTag && !enumTag) { 86 | return; 87 | } 88 | } 89 | 90 | const fullname = getFullName(statement); 91 | if (!fullname) { 92 | return; 93 | } 94 | const root = fullname[0]; 95 | if (root !== 'goog' && root !== 'proto2' && root !== 'osapi' && root !== 'svgpan') { 96 | return; 97 | } 98 | if (isToIgnore(fullname.join('.'))) { 99 | return; 100 | } 101 | const name = popOrThrow(fullname); 102 | let className: string | null = null; 103 | let isStatic = false; 104 | if (fullname[fullname.length - 1] === 'prototype') { 105 | if (isEmptyOverride(doc, statement)) { 106 | return; 107 | } 108 | // consume 'prototype' 109 | fullname.pop(); 110 | className = popOrThrow(fullname); 111 | } else if (isStaticMember(fullname, declarations)) { 112 | if (!isClass && !isInterface && !enumTag && !typedefTag) { 113 | className = popOrThrow(fullname); 114 | isStatic = true; 115 | } 116 | } 117 | const moduleName = fullname.join('.'); 118 | 119 | if (moduleName === 'goog.global') { 120 | return; 121 | } 122 | 123 | let moduleInfo: ModuleInfo = declarations[moduleName]; 124 | if (!moduleInfo) { 125 | moduleInfo = declarations[moduleName] = { 126 | vars: [], 127 | typedefs: [], 128 | functions: [], 129 | enums: [], 130 | classes: [], 131 | classIndex: {}, 132 | }; 133 | } 134 | 135 | let classInfo: ClassInfo | null = null; 136 | if (moduleInfo && className) { 137 | classInfo = moduleInfo.classIndex[className]; 138 | } 139 | if (className && !classInfo) { 140 | // the class is private 141 | return; 142 | } 143 | 144 | if (isClass || isInterface) { 145 | classInfo = { 146 | name, 147 | type: isClass ? 'ClassType' : 'InterfaceType', 148 | cstr: getClassConstructorAnnotation(doc.tags), 149 | parents: getParentClasses(doc.tags), 150 | templates: getTemplates(doc.tags), 151 | methods: [], 152 | props: [], 153 | comment: comment, 154 | }; 155 | moduleInfo.classes.push(classInfo); 156 | moduleInfo.classIndex[name] = classInfo; 157 | return; 158 | } 159 | 160 | if (isFunctionDeclaration(statement, doc.tags)) { 161 | const functionInfo: FunctionInfo = { 162 | name, 163 | type: getFunctionAnnotation(doc.tags), 164 | templates: getTemplates(doc.tags), 165 | isStatic: isStatic, 166 | comment: comment, 167 | }; 168 | 169 | if (className && classInfo) { 170 | classInfo.methods.push(functionInfo); 171 | } else { 172 | moduleInfo.functions.push(functionInfo); 173 | } 174 | return; 175 | } 176 | 177 | if (enumTag) { 178 | if (statement.type !== Syntax.ExpressionStatement) { 179 | throw new Error('ExpressionStatement are expected: ' + statement.type); 180 | } 181 | moduleInfo.enums.push({ 182 | name: name, 183 | type: getTsType(enumTag.type), 184 | keys: getEnumKeys(statement), 185 | original: getOriginalEnum(statement), 186 | comment: comment, 187 | }); 188 | return; 189 | } 190 | 191 | if (typedefTag) { 192 | moduleInfo.typedefs.push({ 193 | name: name, 194 | type: getTsType(typedefTag.type), 195 | comment: comment, 196 | }); 197 | return; 198 | } 199 | 200 | const varInfo = { 201 | name: name, 202 | type: getTypeAnnotation(doc.tags, statement), 203 | isStatic: isStatic, 204 | comment: comment, 205 | }; 206 | if (className) { 207 | moduleInfo.classIndex[className].props.push(varInfo); 208 | } else { 209 | moduleInfo.vars.push(varInfo); 210 | } 211 | } 212 | 213 | function popOrThrow(array: T[]): T { 214 | const lastItem = array.pop(); 215 | if (lastItem === undefined) { 216 | throw new Error('pop failed: array is empty unexpectedly'); 217 | } 218 | return lastItem; 219 | } 220 | 221 | function extractProvide( 222 | statement: estree.Statement | estree.ModuleDeclaration, 223 | provides: string[] 224 | ): boolean { 225 | if ( 226 | statement.type === Syntax.ExpressionStatement && 227 | statement.expression.type === Syntax.CallExpression 228 | ) { 229 | const callExp = statement.expression; 230 | const firstArg = callExp.arguments[0]; 231 | if ( 232 | firstArg && 233 | firstArg.type === Syntax.Literal && 234 | deepEqual(espurify(callExp.callee), { 235 | type: 'MemberExpression', 236 | computed: false, 237 | object: { 238 | type: 'Identifier', 239 | name: 'goog', 240 | }, 241 | property: { 242 | type: 'Identifier', 243 | name: 'provide', 244 | }, 245 | }) 246 | ) { 247 | if (typeof firstArg.value !== 'string') { 248 | throw new Error('Unexpected value: ' + firstArg.value); 249 | } 250 | provides.push(firstArg.value!); 251 | return true; 252 | } 253 | } 254 | return false; 255 | } 256 | 257 | function isToIgnore(name: string): boolean { 258 | const ignoreList = { 259 | 'goog.debug.LogManager': true, 260 | 'goog.net.BrowserChannel.LogSaver': true, 261 | 'goog.net.cookies.MAX_COOKIE_LENGTH': true, 262 | 'goog.ui.AbstractSpellChecker.prototype.getHandler': true, 263 | }; 264 | return name in ignoreList; 265 | } 266 | 267 | function isStaticMember(fullname: string[], declarations: Record): boolean { 268 | const className = fullname[fullname.length - 1]; 269 | const moduleName = fullname.slice(0, -1).join('.'); 270 | const moduleInfo = declarations[moduleName]; 271 | if (moduleInfo && moduleInfo.classIndex[className]) { 272 | // InterfaceType doesn't have static members. 273 | return moduleInfo.classIndex[className].type === 'ClassType'; 274 | } 275 | return false; 276 | } 277 | 278 | function isPrivate(tags: doctrine.Tag[]): boolean { 279 | return tags.some(tag => tag.title === 'private'); 280 | } 281 | 282 | function isEmptyOverride( 283 | doc: doctrine.Annotation, 284 | statement: estree.Statement | estree.ModuleDeclaration 285 | ): boolean { 286 | const tags = doc.tags; 287 | let hasOverride = false; 288 | let hasDescription = !!doc.description; 289 | let hasType = false; 290 | tags.forEach(tag => { 291 | const title = tag.title; 292 | hasOverride = hasOverride || title === 'override'; 293 | hasDescription = hasDescription || (!!tag.description && tag.description !== '*'); 294 | hasType = 295 | hasType || 296 | title === 'param' || 297 | title === 'return' || 298 | title === 'this' || 299 | title === 'type' || 300 | title === 'template'; 301 | }); 302 | 303 | if (hasOverride && !hasType) { 304 | // return !(hasDescription && isAssignement(statement)); 305 | return true; 306 | } 307 | 308 | return false; 309 | } 310 | 311 | function getEnumTag(tags: doctrine.Tag[]): doctrine.Tag | null { 312 | for (let i = 0; i < tags.length; i++) { 313 | if (tags[i].title === 'enum') { 314 | return tags[i]; 315 | } 316 | } 317 | return null; 318 | } 319 | 320 | function getTypedefTag(tags: doctrine.Tag[]): doctrine.Tag | null { 321 | for (let i = 0; i < tags.length; i++) { 322 | if (tags[i].title === 'typedef') { 323 | return tags[i]; 324 | } 325 | } 326 | return null; 327 | } 328 | 329 | /** 330 | * `foo.Bar = {A: 'a', B: 'b'}` => ['A', 'B'] 331 | */ 332 | function getEnumKeys(statement: estree.ExpressionStatement): string[] { 333 | if (statement.expression.type !== Syntax.AssignmentExpression) { 334 | throw new Error('AssignmentExpression are expected: ' + statement.expression.type); 335 | } 336 | if (statement.expression.right.type !== 'ObjectExpression') { 337 | return []; 338 | } 339 | return statement.expression.right.properties.map(property => { 340 | const key = property.key; 341 | switch (key.type) { 342 | case 'Identifier': 343 | return key.name; 344 | case 'Literal': 345 | if (!key.raw) { 346 | throw new Error('Unexpected literal raw: ' + key.raw); 347 | } 348 | return key.raw; 349 | default: 350 | throw new Error(`getEnumKeys(): Unexpected key: ${key.type}`); 351 | } 352 | }); 353 | } 354 | 355 | /** 356 | * `goog.Foo = goog.Bar` => `goog.Bar` 357 | */ 358 | function getOriginalEnum(statement: estree.ExpressionStatement): string | null { 359 | if (statement.expression.type !== Syntax.AssignmentExpression) { 360 | throw new Error('AssignmentExpression are expected: ' + statement.expression.type); 361 | } 362 | const right = statement.expression.right; 363 | if (right.type === 'Identifier' || right.type === 'MemberExpression') { 364 | return getMemberExpressionNameListNoLiteral(right).join('.'); 365 | } 366 | return null; 367 | } 368 | 369 | interface GetTsTypeOptions { 370 | isChildOfTypeApplication?: boolean; 371 | isUnionTypeMember?: boolean; 372 | isRestType?: boolean; 373 | } 374 | 375 | function getTsType(type: doctrine.Type | null | undefined, opts?: GetTsTypeOptions): string { 376 | opts = opts || {}; 377 | if (!type) { 378 | // no type property if doctrine fails to parse type. 379 | return 'any'; 380 | } 381 | 382 | /* eslint-disable no-case-declarations */ 383 | // TODO: use doctrine.Styntax 384 | switch (type.type) { 385 | case 'NameExpression': 386 | let typeName = util.renameReservedModuleName(type.name); 387 | typeName = replaceTypeName(typeName, opts); 388 | const paramNum = getTsGenericTypeParamNum(type.name); 389 | if (paramNum && !opts.isChildOfTypeApplication) { 390 | const typeParams: string[] = []; 391 | for (let i = 0; i < paramNum; i++) { 392 | typeParams.push('any'); 393 | } 394 | return `${typeName}<${typeParams.join(', ')}>`; 395 | } 396 | return typeName; 397 | case 'AllLiteral': 398 | case 'NullableLiteral': 399 | return 'any'; 400 | case 'VoidLiteral': 401 | case 'NullLiteral': 402 | case 'UndefinedLiteral': 403 | return 'void'; 404 | case 'OptionalType': 405 | return getTsType(type.expression); 406 | case 'NullableType': 407 | case 'NonNullableType': 408 | // Every types in TypeScript is a nullable. 409 | // There is not any non-nullables. 410 | return getTsType(type.expression, opts); 411 | case 'UnionType': 412 | let union = type.elements.map(el => getTsType(el, {isUnionTypeMember: true})).join('|'); 413 | if (opts.isRestType) { 414 | union = `(${union})`; 415 | } 416 | return union; 417 | case 'RestType': 418 | return `${getTsType(type.expression, {isRestType: true})}[]`; 419 | case 'TypeApplication': 420 | return getTypeApplicationString(type); 421 | case 'FunctionType': 422 | const params = type.params.map((paramType, index) => ({ 423 | type: getTsType(paramType), 424 | name: getArgName(`arg${index}`, paramType), 425 | })); 426 | return toFunctionTypeString(params, getTsType(type.result), opts); 427 | case 'RecordType': 428 | return toRecordTypeString(type); 429 | default: 430 | throw new Error(`Unexpected type: ${type.type}`); 431 | } 432 | /* eslint-enable no-case-declarations */ 433 | } 434 | 435 | function getTypeApplicationString(type: doctrine.type.TypeApplication): string { 436 | const baseType = getTsType(type.expression, {isChildOfTypeApplication: true}); 437 | if (baseType === 'Object') { 438 | return getObjectTypeApplicationString(type.applications); 439 | } else if (isNotTsGenericType(baseType)) { 440 | return baseType; 441 | } 442 | const paramStrList = type.applications.map(app => getTsType(app)); 443 | const paramNum = getTsGenericTypeParamNum(baseType); 444 | if (paramStrList.length < paramNum) { 445 | const diff = paramNum - paramStrList.length; 446 | for (let i = 0; i < diff; i++) { 447 | paramStrList.push('any'); 448 | } 449 | } 450 | return `${baseType}<${paramStrList.join(', ')}>`; 451 | } 452 | 453 | function getObjectTypeApplicationString(applications: doctrine.Type[]): string { 454 | let indexType = 'string'; 455 | let valueType; 456 | if (applications.length === 1) { 457 | valueType = getTsType(applications[0]); 458 | } else if (applications.length === 2) { 459 | indexType = getTsType(applications[0]); 460 | valueType = getTsType(applications[1]); 461 | } else { 462 | throw new Error(`Object cannot accept type application lenght: ${applications.length}`); 463 | } 464 | 465 | if (indexType !== 'string' && indexType !== 'number') { 466 | indexType = 'string'; 467 | } 468 | return `{[index: ${indexType}]: ${valueType}}`; 469 | } 470 | 471 | function isNotTsGenericType(name: string): boolean { 472 | const nonGenericTypes = { 473 | Object: true, 474 | // TODO: Iterator and ArrayLike has a type parameter implicitly. 475 | 'goog.iter.Iterable': true, 476 | 'goog.array.ArrayLike': true, 477 | }; 478 | return name in nonGenericTypes; 479 | } 480 | 481 | function getTsGenericTypeParamNum(name: string): number { 482 | const genericTypes: Record = { 483 | Array: 1, 484 | IThenable: 1, 485 | Map: 2, 486 | NodeListOf: 1, 487 | Set: 1, 488 | WeakMap: 2, 489 | 'goog.Promise': 2, 490 | 'goog.Thenable': 1, 491 | 'goog.async.Deferred': 1, 492 | 'goog.dom.TagName': 1, 493 | 'goog.events.EventHandler': 1, 494 | 'goog.events.EventId': 1, 495 | 'goog.iter.Iterator': 1, 496 | 'goog.structs.Heap': 2, 497 | 'goog.structs.Map': 2, 498 | 'goog.structs.Pool': 1, 499 | 'goog.structs.PriorityPool': 1, 500 | 'goog.structs.Set': 1, 501 | 'goog.structs.TreeNode': 2, 502 | }; 503 | return genericTypes[name] || 0; 504 | } 505 | 506 | function getArgName(name: string, type: doctrine.Type | null | undefined): string { 507 | if (isReservedWord(name)) { 508 | name += '_'; 509 | } 510 | 511 | if (!type) { 512 | return name; 513 | } 514 | 515 | switch (type.type) { 516 | case 'OptionalType': 517 | return `${name}?`; 518 | case 'RestType': 519 | return `...${name}`; 520 | default: 521 | return name; 522 | } 523 | } 524 | 525 | function isReservedWord(name: string): boolean { 526 | return name === 'class'; 527 | } 528 | 529 | function getFunctionAnnotation( 530 | tags: doctrine.Tag[], 531 | opt_ignoreReturn?: boolean, 532 | opt_ignoreTemplate?: boolean 533 | ): string { 534 | const params: {type: any; name: string}[] = []; 535 | let returns = ''; 536 | 537 | tags.forEach(tag => { 538 | switch (tag.title) { 539 | case 'param': 540 | if (!tag.name) { 541 | throw new Error('tag.name of param is undefined: ' + tag.name); 542 | } 543 | params.push({type: getTsType(tag.type), name: getArgName(tag.name, tag.type)}); 544 | break; 545 | case 'return': 546 | if (!opt_ignoreReturn) { 547 | returns = getTsType(tag.type); 548 | } 549 | break; 550 | default: 551 | break; 552 | } 553 | }); 554 | 555 | returns = returns || 'void'; 556 | const args = toFunctionArgsString(params); 557 | if (opt_ignoreReturn) { 558 | return args; 559 | } 560 | return `${args}: ${returns}`; 561 | } 562 | 563 | function getTemplates(tags: doctrine.Tag[]): string[] { 564 | let templates: string[] = []; 565 | tags.some(tag => { 566 | if (tag.title === 'template') { 567 | templates = tag.description!.split(',').map(t => t.trim()); 568 | return true; 569 | } 570 | return false; 571 | }); 572 | return templates; 573 | } 574 | 575 | function getClassConstructorAnnotation(tags: doctrine.Tag[]): string { 576 | return getFunctionAnnotation(tags, true, true); 577 | } 578 | 579 | function getParentClasses(tags: doctrine.Tag[]): string[] { 580 | return tags.filter(tag => tag.title === 'extends').map(tag => getTsType(tag.type)); 581 | } 582 | 583 | function getTypeAnnotation( 584 | tags: doctrine.Tag[], 585 | statement: estree.Statement | estree.ModuleDeclaration 586 | ): string { 587 | const typeTag = tags.find(tag => tag.title === 'type'); 588 | if (typeTag) { 589 | return getTsType(typeTag.type); 590 | } else if (isAssignement(statement)) { 591 | return 'any'; 592 | } else { 593 | console.error(tags); 594 | throw new Error('Unsupported type annotations.'); 595 | } 596 | } 597 | 598 | function toRecordTypeString(tag: doctrine.type.RecordType): string { 599 | return `{${tag.fields.map(field => `${field.key}: ${getTsType(field.value)}`).join('; ')}}`; 600 | } 601 | 602 | function toFunctionTypeString( 603 | params: {type: string; name: string}[], 604 | ret: string, 605 | opts?: GetTsTypeOptions 606 | ): string { 607 | opts = opts || {}; 608 | const args = toFunctionArgsString(params); 609 | const returns = ret ? ret : 'void'; 610 | let str = `${args} => ${returns}`; 611 | if (opts.isUnionTypeMember) { 612 | str = `(${str})`; 613 | } 614 | return str; 615 | } 616 | 617 | function toFunctionArgsString(params: {type: string; name: string}[]): string { 618 | return `(${params.map(param => `${param.name}: ${param.type}`).join(', ')})`; 619 | } 620 | 621 | /** 622 | * `foo = bar;` 623 | */ 624 | interface AssignmentStatement extends estree.ExpressionStatement { 625 | expression: estree.AssignmentExpression; 626 | } 627 | 628 | function isAssignement( 629 | statement: estree.Statement | estree.ModuleDeclaration 630 | ): statement is AssignmentStatement { 631 | return ( 632 | statement.type === Syntax.ExpressionStatement && 633 | statement.expression.type === Syntax.AssignmentExpression 634 | ); 635 | } 636 | 637 | function isFunctionDeclaration( 638 | statement: estree.Statement | estree.ModuleDeclaration, 639 | tags: doctrine.Tag[] 640 | ): boolean { 641 | const isFunction = tags.some(tag => tag.title === 'param' || tag.title === 'return'); 642 | 643 | if (isFunction) { 644 | return true; 645 | } 646 | 647 | if (isAssignement(statement)) { 648 | if (statement.expression.right.type === Syntax.FunctionExpression) { 649 | return true; 650 | } else if (statement.expression.right.type === Syntax.MemberExpression) { 651 | const right = getMemberExpressionNameListNoLiteral(statement.expression.right).join('.'); 652 | switch (right) { 653 | case 'goog.abstractMethod': 654 | case 'goog.nullFunction': 655 | case 'goog.functions.TRUE': 656 | case 'goog.functions.FALSE': 657 | case 'goog.functions.NULL': 658 | return true; 659 | default: 660 | // ignore 661 | } 662 | } 663 | return false; 664 | } 665 | 666 | const isNotFunction = tags.some(tag => { 667 | switch (tag.title) { 668 | case 'const': 669 | case 'constructor': 670 | case 'define': 671 | case 'dict': 672 | case 'enum': 673 | case 'extends': 674 | case 'implements': 675 | case 'interface': 676 | case 'record': 677 | case 'struct': 678 | case 'type': 679 | case 'typedef': 680 | return true; 681 | default: 682 | return false; 683 | } 684 | }); 685 | return !isNotFunction; 686 | } 687 | 688 | function isClassDeclaration( 689 | statement: estree.Statement | estree.ModuleDeclaration, 690 | tags: doctrine.Tag[] 691 | ): boolean { 692 | return tags.some(tag => tag.title === 'constructor'); 693 | } 694 | 695 | function isInterfaceDeclaration( 696 | statement: estree.Statement | estree.ModuleDeclaration, 697 | tags: doctrine.Tag[] 698 | ): boolean { 699 | return tags.some(tag => tag.title === 'interface' || tag.title === 'record'); 700 | } 701 | 702 | function getFullName(statement: estree.Statement | estree.ModuleDeclaration): string[] | null { 703 | switch (statement.type) { 704 | case Syntax.ExpressionStatement: 705 | return getFullNameFromExpressionStatement(statement); 706 | case Syntax.FunctionDeclaration: 707 | // function declarations should not be exported. 708 | return null; 709 | case Syntax.VariableDeclaration: 710 | return getFullNameFromVariableDeclaration(statement); 711 | default: 712 | throw new Error('Unexpected statement'); 713 | } 714 | } 715 | 716 | function getFullNameFromVariableDeclaration(statement: estree.VariableDeclaration) { 717 | // No variable declarations in Closure Library 718 | return null; 719 | } 720 | 721 | function getFullNameFromExpressionStatement( 722 | statement: estree.ExpressionStatement 723 | ): string[] | null { 724 | const expression = statement.expression; 725 | let targetExpression: estree.MemberExpression | estree.Identifier; 726 | switch (expression.type) { 727 | case Syntax.AssignmentExpression: 728 | if ( 729 | expression.left.type !== Syntax.MemberExpression && 730 | expression.left.type !== Syntax.Identifier 731 | ) { 732 | throw new Error(`Unexpected expression: ${expression.left.type}`); 733 | } 734 | targetExpression = expression.left; 735 | break; 736 | case Syntax.MemberExpression: 737 | targetExpression = expression; 738 | break; 739 | case Syntax.CallExpression: 740 | // ex: @fileoverview befores goog.provide('foo') 741 | return null; 742 | default: 743 | console.error(statement); 744 | throw new Error(`Unexpected expression: ${expression.type}`); 745 | } 746 | 747 | return getMemberExpressionNameList(targetExpression); 748 | } 749 | 750 | function getMemberExpressionNameListNoLiteral( 751 | expression: estree.MemberExpression | estree.Identifier 752 | ): string[] { 753 | const nameList = getMemberExpressionNameList(expression); 754 | if (!nameList) { 755 | console.error(expression); 756 | throw new Error('The expressoin includes a literal unexpectedly'); 757 | } 758 | return nameList; 759 | } 760 | 761 | /** 762 | * @return {string[]|null} null if the expression includes a literal. 763 | */ 764 | function getMemberExpressionNameList( 765 | expression: estree.MemberExpression | estree.Identifier 766 | ): string[] | null { 767 | const fullname: string[] = []; 768 | let includeLiteral = false; 769 | estraverse.traverse(expression, { 770 | enter(node, parent) { 771 | if ((node.type === 'MemberExpression' && node.computed) || node.type === Syntax.Literal) { 772 | includeLiteral = true; 773 | this.break(); 774 | } 775 | }, 776 | leave(node, parent) { 777 | if (node.type === Syntax.Identifier) { 778 | fullname.push(node.name); 779 | } 780 | }, 781 | }); 782 | if (includeLiteral) { 783 | return null; 784 | } 785 | return fullname; 786 | } 787 | 788 | function replaceTypeName(name: string, opts: GetTsTypeOptions): string { 789 | const map: Record = { 790 | EventTarget: 'goog.globalEventTarget', 791 | WebWorker: 'Worker', 792 | // TODO: goog.Thenable and Thenable is confusing, Thenable is renamed to _Thenable temporarily. 793 | Thenable: '_Thenable', 794 | // deprecated: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem 795 | HTMLMenuItemElement: 'HTMLElement', 796 | // deprecated: https://developer.mozilla.org/en-US/docs/Web/API/HTMLIsIndexElement 797 | HTMLIsIndexElement: 'HTMLElement', 798 | }; 799 | const genericsMap: Record = { 800 | NodeList: 'NodeListOf', 801 | }; 802 | if (opts.isChildOfTypeApplication && name in genericsMap) { 803 | return genericsMap[name]; 804 | } else if (name in map) { 805 | return map[name]; 806 | } else { 807 | return name; 808 | } 809 | } 810 | -------------------------------------------------------------------------------- /src/printer.ts: -------------------------------------------------------------------------------- 1 | import intersection from 'lodash/intersection'; 2 | import * as util from './util'; 3 | import { 4 | ModuleInfo, 5 | TypeDefInfo, 6 | EnumInfo, 7 | VarInfo, 8 | FunctionInfo, 9 | ClassInfo, 10 | InfoBase, 11 | } from './types'; 12 | 13 | export default function outputDeclarations( 14 | declarations: Record, 15 | provides: string[] 16 | ): string { 17 | const output: string[] = []; 18 | output.push(outputProvides(declarations, provides)); 19 | for (const name in declarations) { 20 | output.push(outputModule(declarations[name], name)); 21 | } 22 | let outputString = output.filter(str => !!str).join('\n\n'); 23 | if (outputString) { 24 | outputString += '\n'; 25 | } 26 | return outputString; 27 | } 28 | 29 | function outputProvides(declarations: Record, provided: string[]): string { 30 | if (!provided.length) { 31 | return ''; 32 | } 33 | let provides: string[] = []; 34 | for (const moduleName in declarations) { 35 | const module = declarations[moduleName]; 36 | const appendModule = (item: InfoBase) => `${moduleName}.${item.name}`; 37 | if (module.vars.length > 0 || module.functions.length > 0) { 38 | provides.push(moduleName); 39 | } 40 | 41 | provides = provides.concat(module.enums.map(appendModule)); 42 | provides = provides.concat( 43 | module.classes.filter(c => c.type === 'ClassType').map(appendModule) 44 | ); 45 | } 46 | provides = intersection(provides, provided); 47 | if (!provides.length) { 48 | return ''; 49 | } 50 | const output = ['declare module goog {']; 51 | const indent = ' '; 52 | output.push(provides.map(outputProvide.bind(null, indent)).join('\n')); 53 | output.push('}'); 54 | return output.join('\n'); 55 | } 56 | 57 | function outputProvide(indent: string, name: string): string { 58 | const resolvedName = util.renameReservedModuleName(name); 59 | return `${indent}function require(name: '${name}'): typeof ${resolvedName};`; 60 | } 61 | 62 | function outputModule(moduleDeclaration: ModuleInfo, name: string): string { 63 | name = util.renameReservedModuleName(name); 64 | const output = [`declare module ${name} {`]; 65 | const indent = ' '; 66 | // TODO: keep original order 67 | output.push(moduleDeclaration.enums.map(outputEnumDeclaration.bind(null, indent)).join('\n')); 68 | output.push( 69 | moduleDeclaration.typedefs.map(outputTypedefDeclaration.bind(null, indent)).join('\n') 70 | ); 71 | output.push(moduleDeclaration.classes.map(outputClassDeclaration.bind(null, indent)).join('\n')); 72 | output.push(moduleDeclaration.vars.map(outputVarDeclaration.bind(null, indent)).join('\n')); 73 | output.push( 74 | moduleDeclaration.functions.map(outputFunctionDeclaration.bind(null, indent)).join('\n') 75 | ); 76 | output.push('}'); 77 | return output.filter(section => !!section).join('\n'); 78 | } 79 | 80 | function outputTypedefDeclaration(indent: string, declare: TypeDefInfo): string { 81 | const output = `/*${declare.comment.value}*/`.split('\n'); 82 | output.push(`type ${declare.name} = ${declare.type};`); 83 | return `\n${output.map(line => indent + line).join('\n')}`; 84 | } 85 | 86 | function outputEnumDeclaration(indent: string, declare: EnumInfo): string { 87 | const output = `/*${declare.comment.value}*/`.split('\n'); 88 | if (declare.original) { 89 | // just copy 90 | output.push(`export import ${declare.name} = ${declare.original};`); 91 | } else { 92 | output.push(`type ${declare.name} = ${declare.type};`); 93 | output.push(`var ${declare.name}: {`); 94 | declare.keys.forEach(key => { 95 | output.push(` ${key}: ${declare.name};`); 96 | }); 97 | output.push('};'); 98 | } 99 | return `\n${output.map(line => indent + line).join('\n')}`; 100 | } 101 | 102 | function outputVarDeclaration(indent: string, declare: VarInfo): string { 103 | const output = `/*${declare.comment.value}*/`.split('\n'); 104 | output.push(`var ${declare.name}: ${declare.type};`); 105 | return `\n${output.map(line => indent + line).join('\n')}`; 106 | } 107 | 108 | function outputFunctionDeclaration(indent: string, declare: FunctionInfo): string { 109 | const output = `/*${declare.comment.value}*/`.split('\n'); 110 | output.push(`function ${declare.name}${getTemplateString(declare.templates)}${declare.type};`); 111 | return `\n${output.map(line => indent + line).join('\n')}`; 112 | } 113 | 114 | function outputClassDeclaration(indent: string, declare: ClassInfo): string { 115 | const output = `/*${declare.comment.value}*/`.split('\n'); 116 | let extend = ''; 117 | if (declare.parents.length > 0) { 118 | extend = ` extends ${declare.parents.join(', ')}`; 119 | } 120 | if (declare.type === 'ClassType') { 121 | output.push(`class ${declare.name}${getTemplateString(declare.templates)}${extend} {`); 122 | output.push(` constructor${declare.cstr};`); 123 | } else if (declare.type === 'InterfaceType') { 124 | output.push(`interface ${declare.name}${getTemplateString(declare.templates)}${extend} {`); 125 | } 126 | declare.props.forEach(prop => { 127 | output.push(' '); 128 | output.push(` /*${prop.comment.value}*/`.split('\n').join(`\n ${indent}`)); 129 | output.push(` ${prop.isStatic ? 'static ' : ''}${prop.name}: ${prop.type};`); 130 | }); 131 | declare.methods.forEach(method => { 132 | output.push(' '); 133 | output.push(` /*${method.comment.value}*/`.split('\n').join(`\n ${indent}`)); 134 | output.push( 135 | ` ${method.isStatic ? 'static ' : ''}${method.name}${getTemplateString(method.templates)}${ 136 | method.type 137 | };` 138 | ); 139 | }); 140 | output.push('}'); 141 | return `\n${output.map(line => indent + line).join('\n')}`; 142 | } 143 | 144 | function getTemplateString(templates: string[]): string { 145 | if (templates && templates.length > 0) { 146 | return `<${templates.join(', ')}>`; 147 | } else { 148 | return ''; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import * as estree from 'estree'; 2 | 3 | export interface ModuleInfo { 4 | vars: VarInfo[]; 5 | typedefs: TypeDefInfo[]; 6 | functions: FunctionInfo[]; 7 | enums: EnumInfo[]; 8 | classes: ClassInfo[]; 9 | classIndex: Record; 10 | } 11 | 12 | export interface InfoBase { 13 | name: string; 14 | type: string; 15 | comment: estree.Comment; 16 | } 17 | 18 | export interface VarInfo extends InfoBase { 19 | isStatic: boolean; 20 | } 21 | 22 | export interface ClassInfo extends InfoBase { 23 | type: 'ClassType' | 'InterfaceType'; 24 | cstr: any; 25 | parents: string[]; 26 | templates: string[]; 27 | methods: FunctionInfo[]; 28 | props: VarInfo[]; 29 | } 30 | 31 | export interface FunctionInfo extends InfoBase { 32 | templates: string[]; 33 | isStatic: boolean; 34 | } 35 | 36 | export interface EnumInfo extends InfoBase { 37 | keys: string[]; 38 | original: string | null; 39 | } 40 | 41 | export interface TypeDefInfo extends InfoBase {} 42 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | export function renameReservedModuleName(name: string): string { 2 | return name.replace(/^goog\.string(?=$|\.)/, 'goog.string$'); 3 | } 4 | -------------------------------------------------------------------------------- /test/all.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /test/fixtures/any.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {*} bar 5 | * @return {*} 6 | */ 7 | function foo(bar: any): any; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/any.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {*} bar 3 | * @return {*} 4 | */ 5 | goog.functions.foo = function(bar) { 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/assignment-conditional-expression.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number} a 5 | */ 6 | function foo(a: number): void; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/assignment-conditional-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} a 3 | */ 4 | goog.functions.foo = goog.FOO ? function(a) {} : function(a) {}; 5 | -------------------------------------------------------------------------------- /test/fixtures/builtin-eventtarget.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {EventTarget} bar 5 | * @return {EventTarget} 6 | */ 7 | function foo(bar: goog.globalEventTarget): goog.globalEventTarget; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/builtin-eventtarget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {EventTarget} bar 3 | * @return {EventTarget} 4 | */ 5 | goog.functions.foo = function(bar) { 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/class-constructor.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | */ 7 | class DomHelper { 8 | constructor(document: Document); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/class-constructor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | */ 5 | goog.dom.DomHelper = function(document) { 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/class-empty-override.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @constructor 5 | */ 6 | class Foo { 7 | constructor(); 8 | 9 | /** 10 | * @type {*} 11 | */ 12 | foo1: any; 13 | 14 | /** 15 | * @type {*} 16 | */ 17 | foo2: any; 18 | 19 | /** 20 | * @type {*} 21 | */ 22 | foo3: any; 23 | 24 | /** 25 | * @type {*} 26 | */ 27 | foo4: any; 28 | } 29 | 30 | /** 31 | * @constructor 32 | * @extends {goog.dom.Foo} 33 | */ 34 | class Bar extends goog.dom.Foo { 35 | constructor(); 36 | 37 | /** 38 | * @type {string} 39 | * @override 40 | */ 41 | foo2: string; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/fixtures/class-empty-override.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | goog.dom.Foo = function() {}; 5 | 6 | /** 7 | * @type {*} 8 | */ 9 | goog.dom.Foo.prototype.foo1 = null; 10 | 11 | /** 12 | * @type {*} 13 | */ 14 | goog.dom.Foo.prototype.foo2 = null; 15 | 16 | /** 17 | * @type {*} 18 | */ 19 | goog.dom.Foo.prototype.foo3 = null; 20 | 21 | 22 | /** 23 | * @type {*} 24 | */ 25 | goog.dom.Foo.prototype.foo4 = null; 26 | 27 | /** 28 | * @constructor 29 | * @extends {goog.dom.Foo} 30 | */ 31 | goog.dom.Bar = function() {}; 32 | goog.inherits(goog.dom.Bar, goog.dom.Foo); 33 | 34 | /** 35 | * @override 36 | */ 37 | goog.dom.Bar.prototype.foo1 = ''; 38 | 39 | /** 40 | * @type {string} 41 | * @override 42 | */ 43 | goog.dom.Bar.prototype.foo2; 44 | 45 | /** 46 | * Description. 47 | * @override 48 | */ 49 | goog.dom.Bar.prototype.foo3; 50 | 51 | /** 52 | * Description. 53 | * @override 54 | */ 55 | goog.dom.Bar.prototype.foo4 = ''; 56 | -------------------------------------------------------------------------------- /test/fixtures/class-extends-implements.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @interface 5 | */ 6 | interface Foo { 7 | } 8 | 9 | /** 10 | * @constructor 11 | */ 12 | class Bar { 13 | constructor(); 14 | } 15 | 16 | /** 17 | * @constructor 18 | * @extends {goog.functions.Bar} 19 | * @implements {goog.functions.Foo} 20 | */ 21 | class Baz extends goog.functions.Bar { 22 | constructor(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/class-extends-implements.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @constructor 8 | */ 9 | goog.functions.Bar = function() {}; 10 | 11 | /** 12 | * @constructor 13 | * @extends {goog.functions.Bar} 14 | * @implements {goog.functions.Foo} 15 | */ 16 | goog.functions.Baz = function() {}; 17 | goog.inherits(goog.functions.Baz, goog.functions.Foo); 18 | -------------------------------------------------------------------------------- /test/fixtures/class-extends.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @constructor 5 | */ 6 | class Foo { 7 | constructor(); 8 | } 9 | 10 | /** 11 | * @constructor 12 | * @extends {goog.dom.Foo} 13 | */ 14 | class Bar extends goog.dom.Foo { 15 | constructor(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/class-extends.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | goog.dom.Foo = function() {}; 5 | 6 | /** 7 | * @constructor 8 | * @extends {goog.dom.Foo} 9 | */ 10 | goog.dom.Bar = function() {}; 11 | goog.inherits(goog.dom.Bar, goog.dom.Foo); 12 | -------------------------------------------------------------------------------- /test/fixtures/class-inner.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @constructor 5 | */ 6 | class Foo { 7 | constructor(); 8 | } 9 | } 10 | 11 | declare module goog.dom.Foo { 12 | 13 | /** 14 | * Inner enum 15 | * @enum {string} 16 | */ 17 | type Bar = string; 18 | var Bar: { 19 | A: Bar; 20 | }; 21 | 22 | /** 23 | * Inner typedef 24 | * @typedef {string|number} 25 | */ 26 | type Typedef = string|number; 27 | 28 | /** 29 | * Inner class 30 | * @constructor 31 | */ 32 | class Baz { 33 | constructor(); 34 | } 35 | 36 | /** 37 | * Inner interface 38 | * @interface 39 | */ 40 | interface Bao { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/fixtures/class-inner.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | goog.dom.Foo = function() {}; 5 | 6 | /** 7 | * Inner typedef 8 | * @typedef {string|number} 9 | */ 10 | goog.dom.Foo.Typedef; 11 | 12 | /** 13 | * Inner enum 14 | * @enum {string} 15 | */ 16 | goog.dom.Foo.Bar = { 17 | A: 'aa' 18 | }; 19 | 20 | /** 21 | * Inner class 22 | * @constructor 23 | */ 24 | goog.dom.Foo.Baz = function() {}; 25 | 26 | /** 27 | * Inner interface 28 | * @interface 29 | */ 30 | goog.dom.Foo.Bao = function() {}; 31 | -------------------------------------------------------------------------------- /test/fixtures/class-method-static.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | */ 7 | class DomHelper { 8 | constructor(document: Document); 9 | 10 | /** 11 | * @param {string} str 12 | * @return {number} 13 | */ 14 | static foo(str: string): number; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/class-method-static.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | */ 5 | goog.dom.DomHelper = function(document) { 6 | }; 7 | 8 | /** 9 | * @param {string} str 10 | * @return {number} 11 | */ 12 | goog.dom.DomHelper.foo = function(str) { 13 | return 1; 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/class-method.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | */ 7 | class DomHelper { 8 | constructor(document: Document); 9 | 10 | /** 11 | * @param {string} str 12 | * @return {number} 13 | */ 14 | foo(str: string): number; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/class-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | */ 5 | goog.dom.DomHelper = function(document) { 6 | }; 7 | 8 | /** 9 | * @param {string} str 10 | * @return {number} 11 | */ 12 | goog.dom.DomHelper.prototype.foo = function(str) { 13 | return 1; 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/class-private.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | * @private 7 | */ 8 | interface DomHelper { 9 | 10 | /** 11 | * @type {string} 12 | */ 13 | foo: string; 14 | 15 | /** 16 | * @param {string} str 17 | * @return {number} 18 | */ 19 | bar(str: string): number; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/class-private.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | * @private 5 | */ 6 | goog.dom.DomHelper = function(document) { 7 | }; 8 | 9 | /** 10 | * @type {string} 11 | */ 12 | goog.dom.DomHelper.prototype.foo = ''; 13 | 14 | /** 15 | * @param {string} str 16 | * @return {number} 17 | */ 18 | goog.dom.DomHelper.prototype.bar = function(str) { 19 | return 1; 20 | }; 21 | -------------------------------------------------------------------------------- /test/fixtures/class-property-static.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | */ 7 | class DomHelper { 8 | constructor(document: Document); 9 | 10 | /** 11 | * @type {string} 12 | */ 13 | static foo: string; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/class-property-static.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | */ 5 | goog.dom.DomHelper = function(document) { 6 | }; 7 | 8 | /** 9 | * @type {string} 10 | */ 11 | goog.dom.DomHelper.foo = ''; 12 | -------------------------------------------------------------------------------- /test/fixtures/class-property.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @param {Document} document 5 | * @constructor 6 | */ 7 | class DomHelper { 8 | constructor(document: Document); 9 | 10 | /** 11 | * @type {string} 12 | */ 13 | foo: string; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/class-property.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Document} document 3 | * @constructor 4 | */ 5 | goog.dom.DomHelper = function(document) { 6 | }; 7 | 8 | /** 9 | * @type {string} 10 | */ 11 | goog.dom.DomHelper.prototype.foo = ''; 12 | -------------------------------------------------------------------------------- /test/fixtures/enum-copy.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | 3 | /** 4 | * @enum {string} 5 | */ 6 | type Foo = string; 7 | var Foo: { 8 | FOO: Foo; 9 | BAR: Foo; 10 | BAZ: Foo; 11 | }; 12 | 13 | /** 14 | * @enum {string} 15 | * @deprecated 16 | */ 17 | export import Bar = goog.Foo; 18 | } 19 | -------------------------------------------------------------------------------- /test/fixtures/enum-copy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum {string} 3 | */ 4 | goog.Foo = { 5 | FOO: 'foo', 6 | BAR: 'bar', 7 | BAZ: 'baz' 8 | }; 9 | 10 | /** 11 | * @enum {string} 12 | * @deprecated 13 | */ 14 | goog.Bar = goog.Foo; 15 | -------------------------------------------------------------------------------- /test/fixtures/enum-literal.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | 3 | /** 4 | * @enum {string} 5 | */ 6 | type Foo = string; 7 | var Foo: { 8 | 1: Foo; 9 | 2: Foo; 10 | 3: Foo; 11 | }; 12 | 13 | /** 14 | * @enum {string} 15 | */ 16 | type Bar = string; 17 | var Bar: { 18 | '*': Bar; 19 | '=': Bar; 20 | '|': Bar; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/enum-literal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum {string} 3 | */ 4 | goog.Foo = { 5 | 1: 'foo', 6 | 2: 'bar', 7 | 3: 'baz' 8 | }; 9 | 10 | /** 11 | * @enum {string} 12 | */ 13 | goog.Bar = { 14 | '*': 'foo', 15 | '=': 'bar', 16 | '|': 'baz' 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/enum-private.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | 3 | /** 4 | * @enum {string} 5 | * @private 6 | */ 7 | type Foo = string; 8 | var Foo: { 9 | FOO: Foo; 10 | BAR: Foo; 11 | BAZ: Foo; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/enum-private.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum {string} 3 | * @private 4 | */ 5 | goog.Foo = { 6 | FOO: 'foo', 7 | BAR: 'bar', 8 | BAZ: 'baz' 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/enum.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | 3 | /** 4 | * @enum {string} 5 | */ 6 | type Foo = string; 7 | var Foo: { 8 | FOO: Foo; 9 | BAR: Foo; 10 | BAZ: Foo; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/enum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum {string} 3 | */ 4 | goog.Foo = { 5 | FOO: 'foo', 6 | BAR: 'bar', 7 | BAZ: 'baz' 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/expression-statement.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {string} 5 | */ 6 | var foo: string; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/expression-statement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {string} 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/fixtures/function-type.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {function(string, number): boolean} 5 | */ 6 | var foo: (arg0: string, arg1: number) => boolean; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/function-type.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {function(string, number): boolean} 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/fixtures/functiondeclaration.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teppeis/closure-ts/fa6b084eaeb84936b16da1dfdfb8f90fad273026/test/fixtures/functiondeclaration.d.ts -------------------------------------------------------------------------------- /test/fixtures/functiondeclaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Foo! 3 | * @param {number} num It's number. 4 | * @param {string} str 5 | */ 6 | function foo(num, str) { 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/functions.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * Foo! 5 | * @param {number} num It's number. 6 | * @param {string} str 7 | * @return {Date} 8 | */ 9 | function foo(num: number, str: string): Date; 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Foo! 3 | * @param {number} num It's number. 4 | * @param {string} str 5 | * @return {Date} 6 | */ 7 | goog.functions.foo = function(num, str) { 8 | return new Date(); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/functiontype-rest-uknown.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {function(...)} 5 | */ 6 | var foo: (...arg0: any[]) => any; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/functiontype-rest-uknown.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {function(...)} 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/fixtures/functiontype-rest.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {function(...number): boolean} 5 | */ 6 | var foo: (...arg0: number[]) => boolean; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/functiontype-rest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {function(...number): boolean} 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/fixtures/generic-class.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @interface 5 | * @template T, S 6 | */ 7 | interface Foo { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/generic-class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | * @template T, S 4 | */ 5 | goog.dom.Foo = function() {}; 6 | -------------------------------------------------------------------------------- /test/fixtures/generic-function.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {T} a 5 | * @return {T} 6 | * @template T 7 | */ 8 | function foo(a: T): T; 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/generic-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {T} a 3 | * @return {T} 4 | * @template T 5 | */ 6 | goog.functions.foo = function(a) { 7 | return a; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/generic-interface.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @constructor 5 | * @template T, S 6 | */ 7 | class Foo { 8 | constructor(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/generic-interface.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | * @template T, S 4 | */ 5 | goog.dom.Foo = function() {}; 6 | -------------------------------------------------------------------------------- /test/fixtures/generic-method.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.dom { 2 | 3 | /** 4 | * @constructor 5 | */ 6 | class Foo { 7 | constructor(); 8 | 9 | /** 10 | * @param {T} t 11 | * @template T 12 | */ 13 | foo(t: T): void; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/generic-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | goog.dom.Foo = function() {}; 5 | 6 | /** 7 | * @param {T} t 8 | * @template T 9 | */ 10 | goog.dom.Foo.prototype.foo = function(t) { 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/generic-no-type-param.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @return {Array} 5 | */ 6 | function foo(): Array; 7 | 8 | /** 9 | * @return {Map} 10 | */ 11 | function bar(): Map; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/generic-no-type-param.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {Array} 3 | */ 4 | goog.functions.foo = function() { 5 | return []; 6 | }; 7 | 8 | /** 9 | * @return {Map} 10 | */ 11 | goog.functions.bar = function() { 12 | return null; 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/generic-wrong-type-param.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @return {goog.Promise.} 5 | */ 6 | function foo(): goog.Promise; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/generic-wrong-type-param.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {goog.Promise.} 3 | */ 4 | goog.functions.foo = function() { 5 | return null; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/generics.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @return {Array.} Array of string. 5 | */ 6 | function foo(): Array; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/generics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {Array.} Array of string. 3 | */ 4 | goog.functions.foo = function() { 5 | return ['foo']; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/goog-global.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teppeis/closure-ts/fa6b084eaeb84936b16da1dfdfb8f90fad273026/test/fixtures/goog-global.d.ts -------------------------------------------------------------------------------- /test/fixtures/goog-global.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {string} 3 | */ 4 | goog.global.CLOSURE_BASE_PATH; 5 | -------------------------------------------------------------------------------- /test/fixtures/goog.provide.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | function require(name: 'goog.functions'): typeof goog.functions; 3 | } 4 | 5 | declare module goog.functions { 6 | 7 | /** 8 | * @param {string} s 9 | * @return {number} 10 | */ 11 | function foo(s: string): number; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/goog.provide.js: -------------------------------------------------------------------------------- 1 | goog.provide('goog.functions'); 2 | 3 | /** 4 | * @param {string} s 5 | * @return {number} 6 | */ 7 | goog.functions.foo = function(s) { 8 | return 1; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/goog.string.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.string$ { 2 | 3 | /** 4 | * @constructor 5 | */ 6 | class Bar { 7 | constructor(); 8 | } 9 | 10 | /** 11 | * @constructor 12 | * @extends {goog.string.Bar} 13 | */ 14 | class Baz extends goog.string$.Bar { 15 | constructor(); 16 | } 17 | 18 | /** 19 | * @param {goog.string.Bar} bar 20 | * @param {function(goog.string.Bar): goog.string.Bar} f 21 | * @return {goog.string.Bar} 22 | */ 23 | function foo(bar: goog.string$.Bar, f: (arg0: goog.string$.Bar) => goog.string$.Bar): goog.string$.Bar; 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/goog.string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | goog.string.Bar = function() {}; 5 | 6 | /** 7 | * @constructor 8 | * @extends {goog.string.Bar} 9 | */ 10 | goog.string.Baz = function() {}; 11 | 12 | /** 13 | * @param {goog.string.Bar} bar 14 | * @param {function(goog.string.Bar): goog.string.Bar} f 15 | * @return {goog.string.Bar} 16 | */ 17 | goog.string.foo = function(bar, f) {}; 18 | -------------------------------------------------------------------------------- /test/fixtures/ignore-list.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teppeis/closure-ts/fa6b084eaeb84936b16da1dfdfb8f90fad273026/test/fixtures/ignore-list.d.ts -------------------------------------------------------------------------------- /test/fixtures/ignore-list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ignore goog.debug.LogManager. 3 | */ 4 | goog.debug.LogManager = {}; 5 | -------------------------------------------------------------------------------- /test/fixtures/ignore-private.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number} num 5 | */ 6 | function foo(num: number): void; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/ignore-private.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | */ 4 | goog.functions.foo = function(num) { 5 | }; 6 | 7 | /** 8 | * @param {string} str 9 | * @private 10 | */ 11 | goog.functions.bar_ = function(str) { 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/interface-extends.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @interface 5 | */ 6 | interface Foo { 7 | } 8 | 9 | /** 10 | * @interface 11 | */ 12 | interface Bar { 13 | } 14 | 15 | /** 16 | * @interface 17 | * @extends {Foo} 18 | * @extends {Bar} 19 | */ 20 | interface Baz extends Foo, Bar { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/interface-extends.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @interface 8 | */ 9 | goog.functions.Bar = function() {}; 10 | 11 | /** 12 | * @interface 13 | * @extends {Foo} 14 | * @extends {Bar} 15 | */ 16 | goog.functions.Baz = function() {}; 17 | -------------------------------------------------------------------------------- /test/fixtures/interface-implements.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @interface 5 | */ 6 | interface Foo { 7 | } 8 | 9 | /** 10 | * @interface 11 | */ 12 | interface Bar { 13 | } 14 | 15 | /** 16 | * @constructor 17 | * @implements {goog.functions.Foo} 18 | * @implements {goog.functions.Bar} 19 | */ 20 | class Baz { 21 | constructor(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/interface-implements.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @interface 8 | */ 9 | goog.functions.Bar = function() {}; 10 | 11 | /** 12 | * @constructor 13 | * @implements {goog.functions.Foo} 14 | * @implements {goog.functions.Bar} 15 | */ 16 | goog.functions.Baz = function() {}; 17 | -------------------------------------------------------------------------------- /test/fixtures/interface-static.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @interface 5 | */ 6 | interface Foo { 7 | } 8 | } 9 | 10 | declare module goog.functions.Foo { 11 | 12 | /** 13 | * @type {number} 14 | */ 15 | var foo: number; 16 | 17 | /** 18 | * @param {number} num 19 | * @return {string} 20 | */ 21 | function bar(num: number): string; 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/interface-static.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @type {number} 8 | */ 9 | goog.functions.Foo.foo; 10 | 11 | /** 12 | * @param {number} num 13 | * @return {string} 14 | */ 15 | goog.functions.Foo.bar; 16 | -------------------------------------------------------------------------------- /test/fixtures/interface.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @interface 5 | */ 6 | interface Foo { 7 | 8 | /** 9 | * @type {number} 10 | */ 11 | foo: number; 12 | 13 | /** 14 | * @param {number} num 15 | * @return {string} 16 | */ 17 | bar(num: number): string; 18 | 19 | /** 20 | * No @param and @return. 21 | */ 22 | baz(): void; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/interface.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @type {number} 8 | */ 9 | goog.functions.Foo.prototype.foo; 10 | 11 | /** 12 | * @param {number} num 13 | * @return {string} 14 | */ 15 | goog.functions.Foo.prototype.bar; 16 | 17 | /** 18 | * No @param and @return. 19 | */ 20 | goog.functions.Foo.prototype.baz; 21 | -------------------------------------------------------------------------------- /test/fixtures/literal-member.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teppeis/closure-ts/fa6b084eaeb84936b16da1dfdfb8f90fad273026/test/fixtures/literal-member.d.ts -------------------------------------------------------------------------------- /test/fixtures/literal-member.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A literal member is ignored. 3 | * @param {string} bar 4 | */ 5 | goog.functions['literal'] = function(bar) {}; 6 | -------------------------------------------------------------------------------- /test/fixtures/multi-functions.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number} num 5 | */ 6 | function foo(num: number): void; 7 | 8 | /** 9 | * @param {string} str 10 | */ 11 | function bar(str: string): void; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/multi-functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | */ 4 | goog.functions.foo = function(num) { 5 | }; 6 | 7 | /** 8 | * @param {string} str 9 | */ 10 | goog.functions.bar = function(str) { 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/multi-leading-comments.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {string} str 5 | * @return {Object} 6 | */ 7 | function foo(str: string): Object; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/multi-leading-comments.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} str 3 | * @return {Object} 4 | */ 5 | /* normal block comment */ 6 | // inline comment 7 | goog.functions.foo = function(str) { 8 | return null; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/no-jsdoc-assignement.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | */ 5 | var foo: any; 6 | 7 | /** 8 | */ 9 | function bar(): void; 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/no-jsdoc-assignement.js: -------------------------------------------------------------------------------- 1 | /** 2 | */ 3 | goog.functions.foo = this; 4 | 5 | /** 6 | */ 7 | goog.functions.bar = goog.abstractMethod; 8 | -------------------------------------------------------------------------------- /test/fixtures/no-jsdoc-function.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | */ 5 | function foo(): void; 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/no-jsdoc-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | */ 3 | goog.functions.foo = function() { 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/nodelist.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @return {NodeList} returns list of Element. 5 | */ 6 | function foo(): NodeListOf; 7 | 8 | /** 9 | * @return {NodeList} returns NodeList. 10 | */ 11 | function bar(): NodeList; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/nodelist.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {NodeList} returns list of Element. 3 | */ 4 | goog.functions.foo = function() { 5 | return null; 6 | }; 7 | 8 | /** 9 | * @return {NodeList} returns NodeList. 10 | */ 11 | goog.functions.bar = function() { 12 | return null; 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/null.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {null} 5 | */ 6 | var foo: void; 7 | 8 | /** 9 | * @type {function(null): null} 10 | */ 11 | var bar: (arg0: void) => void; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/null.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {null} 3 | */ 4 | goog.functions.foo; 5 | 6 | /** 7 | * @type {function(null): null} 8 | */ 9 | goog.functions.bar; 10 | -------------------------------------------------------------------------------- /test/fixtures/nullable-literal.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {?} bar 5 | * @return {?} 6 | */ 7 | function foo(bar: any): any; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/nullable-literal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {?} bar 3 | * @return {?} 4 | */ 5 | goog.functions.foo = function(bar) { 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/nullable.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {?number} num 5 | */ 6 | function foo(num: number): void; 7 | 8 | /** 9 | * @param {!Date} date 10 | */ 11 | function bar(date: Date): void; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/nullable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {?number} num 3 | */ 4 | goog.functions.foo = function(num) { 5 | }; 6 | 7 | /** 8 | * @param {!Date} date 9 | */ 10 | goog.functions.bar = function(date) { 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/object.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {T} item 5 | * @return {Object.} 6 | * @template T 7 | */ 8 | function toObject(item: T): {[index: string]: T}; 9 | 10 | /** 11 | * @return {Object} 12 | */ 13 | function numboolean(): {[index: number]: boolean}; 14 | 15 | /** 16 | * @return {Object} 17 | */ 18 | function dateShouldBeConvertedToString(): {[index: string]: boolean}; 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/object.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {T} item 3 | * @return {Object.} 4 | * @template T 5 | */ 6 | goog.functions.toObject = function(item) { 7 | return null; 8 | }; 9 | 10 | /** 11 | * @return {Object} 12 | */ 13 | goog.functions.numboolean = function() { 14 | return null; 15 | }; 16 | 17 | /** 18 | * @return {Object} 19 | */ 20 | goog.functions.dateShouldBeConvertedToString = function() { 21 | return null; 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/optional.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number=} opt_num 5 | */ 6 | function foo(opt_num?: number): void; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/optional.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number=} opt_num 3 | */ 4 | goog.functions.foo = function(opt_num) { 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/record-type.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {{bar: number, baz: string}} 5 | */ 6 | var foo: {bar: number; baz: string}; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/record-type.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {{bar: number, baz: string}} 3 | */ 4 | goog.functions.foo = { 5 | bar: 1, 6 | baz: 'test' 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/record.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @record 5 | */ 6 | interface Foo { 7 | 8 | /** 9 | * @type {number} 10 | */ 11 | foo: number; 12 | 13 | /** 14 | * @param {number} num 15 | * @return {string} 16 | */ 17 | bar(num: number): string; 18 | 19 | /** 20 | * No @param and @return. 21 | */ 22 | baz(): void; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/record.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @record 3 | */ 4 | goog.functions.Foo = function() {}; 5 | 6 | /** 7 | * @type {number} 8 | */ 9 | goog.functions.Foo.prototype.foo; 10 | 11 | /** 12 | * @param {number} num 13 | * @return {string} 14 | */ 15 | goog.functions.Foo.prototype.bar; 16 | 17 | /** 18 | * No @param and @return. 19 | */ 20 | goog.functions.Foo.prototype.baz; 21 | -------------------------------------------------------------------------------- /test/fixtures/reserved-words.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number} class 5 | */ 6 | function foo(class_: number): void; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/reserved-words.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} class 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/fixtures/roots.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog { 2 | 3 | /** 4 | * @param {number} num 5 | */ 6 | function foo(num: number): void; 7 | } 8 | 9 | declare module proto2 { 10 | 11 | /** 12 | * @param {number} num 13 | */ 14 | function foo(num: number): void; 15 | } 16 | 17 | declare module osapi { 18 | 19 | /** 20 | * @param {number} num 21 | */ 22 | function foo(num: number): void; 23 | } 24 | 25 | declare module svgpan { 26 | 27 | /** 28 | * @param {number} num 29 | */ 30 | function foo(num: number): void; 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/roots.js: -------------------------------------------------------------------------------- 1 | // Export 2 | 3 | /** 4 | * @param {number} num 5 | */ 6 | goog.foo = function(num) {}; 7 | 8 | /** 9 | * @param {number} num 10 | */ 11 | proto2.foo = function(num) {}; 12 | 13 | /** 14 | * @param {number} num 15 | */ 16 | osapi.foo = function(num) {}; 17 | 18 | /** 19 | * @param {number} num 20 | */ 21 | svgpan.foo = function(num) {}; 22 | 23 | // Ignore 24 | 25 | /** 26 | * @param {number} num 27 | */ 28 | global.foo = function(num) {}; 29 | 30 | /** 31 | * @param {number} num 32 | */ 33 | self.foo = function(num) {}; 34 | 35 | 36 | /** 37 | * @param {number} num 38 | */ 39 | window.foo = function(num) {}; 40 | -------------------------------------------------------------------------------- /test/fixtures/typedef-private.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.array { 2 | 3 | /** 4 | * Export private @typedef as interface. 5 | * @private 6 | * @typedef {Array|NodeList|{length: number}} 7 | */ 8 | type ArrayLike = Array|NodeList|{length: number}; 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/typedef-private.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Export private @typedef as interface. 3 | * @private 4 | * @typedef {Array|NodeList|{length: number}} 5 | */ 6 | goog.array.ArrayLike; 7 | -------------------------------------------------------------------------------- /test/fixtures/typedef-record.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.array { 2 | 3 | /** 4 | * @typedef {{length: number, foo: string}} 5 | */ 6 | type ArrayLike = {length: number; foo: string}; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/typedef-record.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {{length: number, foo: string}} 3 | */ 4 | goog.array.ArrayLike; 5 | -------------------------------------------------------------------------------- /test/fixtures/typedef-union.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.array { 2 | 3 | /** 4 | * @typedef {Array|NodeList|{length: number}} 5 | */ 6 | type ArrayLike = Array|NodeList|{length: number}; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/typedef-union.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {Array|NodeList|{length: number}} 3 | */ 4 | goog.array.ArrayLike; 5 | -------------------------------------------------------------------------------- /test/fixtures/undefined.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {undefined} 5 | */ 6 | var foo: void; 7 | 8 | /** 9 | * @type {function(undefined): undefined} 10 | */ 11 | var bar: (arg0: void) => void; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/undefined.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {undefined} 3 | */ 4 | goog.functions.foo; 5 | 6 | /** 7 | * @type {function(undefined): undefined} 8 | */ 9 | goog.functions.bar; 10 | -------------------------------------------------------------------------------- /test/fixtures/union.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {number|string} arg 5 | */ 6 | function foo(arg: number|string): void; 7 | 8 | /** 9 | * @param {Array} arg 10 | * @return {Array} arg 11 | */ 12 | function bar(arg: Array): Array; 13 | 14 | /** 15 | * @param {number|function(string, number): boolean} arg 16 | */ 17 | function baz(arg: number|((arg0: string, arg1: number) => boolean)): void; 18 | 19 | /** 20 | * @param {number|?function(string, number): boolean} arg 21 | */ 22 | function nullable(arg: number|((arg0: string, arg1: number) => boolean)): void; 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/union.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number|string} arg 3 | */ 4 | goog.functions.foo = function(arg) { 5 | }; 6 | 7 | /** 8 | * @param {Array} arg 9 | * @return {Array} arg 10 | */ 11 | goog.functions.bar = function(arg) { 12 | }; 13 | 14 | /** 15 | * @param {number|function(string, number): boolean} arg 16 | */ 17 | goog.functions.baz = function(arg) { 18 | }; 19 | 20 | /** 21 | * @param {number|?function(string, number): boolean} arg 22 | */ 23 | goog.functions.nullable = function(arg) { 24 | }; 25 | -------------------------------------------------------------------------------- /test/fixtures/varargs.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @param {...number} var_nums 5 | */ 6 | function foo(...var_nums: number[]): void; 7 | 8 | /** 9 | * @param {...(number|string)} var_nums 10 | */ 11 | function bar(...var_nums: (number|string)[]): void; 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/varargs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {...number} var_nums 3 | */ 4 | goog.functions.foo = function(var_nums) { 5 | }; 6 | 7 | /** 8 | * @param {...(number|string)} var_nums 9 | */ 10 | goog.functions.bar = function(var_nums) { 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/void.d.ts: -------------------------------------------------------------------------------- 1 | declare module goog.functions { 2 | 3 | /** 4 | * @type {function(): void} 5 | */ 6 | var foo: () => void; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/void.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {function(): void} 3 | */ 4 | goog.functions.foo; 5 | -------------------------------------------------------------------------------- /test/parse.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const diff = require('diff'); 5 | const generator = require('../lib/generator'); 6 | 7 | describe('Generator', () => { 8 | const files = fs.readdirSync(`${__dirname}/fixtures`); 9 | return files 10 | .filter(file => /\.js$/.test(file)) 11 | .forEach(file => 12 | it(file, () => { 13 | const code = fs.readFileSync(`${__dirname}/fixtures/${file}`, 'utf8'); 14 | const actual = generator.generate(code); 15 | const expected = fs.readFileSync( 16 | `${__dirname}/fixtures/${file.replace(/\.js$/, '.d.ts')}`, 17 | 'utf8' 18 | ); 19 | if (actual !== expected) { 20 | diff.diffChars(expected, actual).forEach(part => { 21 | let value; 22 | value = part.value; 23 | value = part.added ? `[+${value}]` : part.removed ? `[-${value}]` : value; 24 | return process.stderr.write(value); 25 | }); 26 | throw new Error('Different result'); 27 | } 28 | }) 29 | ); 30 | }); 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "ES2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | // "lib": [], /* Specify library files to be included in the compilation. */ 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | "outDir": "./lib", /* Redirect output structure to the directory. */ 15 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "composite": true, /* Enable project compilation */ 17 | // "removeComments": true, /* Do not emit comments to output. */ 18 | // "noEmit": true, /* Do not emit outputs. */ 19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 21 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 22 | 23 | /* Strict Type-Checking Options */ 24 | "strict": true, /* Enable all strict type-checking options. */ 25 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 26 | // "strictNullChecks": true, /* Enable strict null checks. */ 27 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 28 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 29 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 30 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 31 | 32 | /* Additional Checks */ 33 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 34 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 35 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 36 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 37 | 38 | /* Module Resolution Options */ 39 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 40 | "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 41 | "paths": { 42 | "*": ["@types/*"] 43 | }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 44 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 45 | // "typeRoots": [], /* List of folders to include type definitions from. */ 46 | // "types": [], /* Type declaration files to be included in compilation. */ 47 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 48 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 49 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 50 | 51 | /* Source Map Options */ 52 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 53 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 54 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 55 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 56 | 57 | /* Experimental Options */ 58 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 59 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 60 | }, 61 | "include": [ 62 | "src" 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /tslint.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const importESLintConfig = require('tslint-import-eslint-config'); 4 | const prettierrc = require('eslint-config-teppeis/.prettierrc'); 5 | module.exports = importESLintConfig({ 6 | extends: require(`${__dirname}/.eslintrc.json`).extends, 7 | }); 8 | 9 | module.exports.extends.push('tslint-plugin-prettier'); 10 | Object.assign(module.exports.rules, { 11 | prettier: [true, prettierrc], 12 | 'valid-jsdoc': false, 13 | 'no-invalid-this': false, 14 | 'no-unused-variable': false, 15 | }); 16 | --------------------------------------------------------------------------------