Skip to content

Commit

Permalink
Add support for ClosureCompiler syntax "typeof T" (#128)
Browse files Browse the repository at this point in the history
* add typeof tests

* add support for typeof syntax

* update readme
  • Loading branch information
aidinabedi authored Apr 22, 2020
1 parent 458f5b6 commit fe18a88
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 7 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Or add this to your JSON configuration:
}
```

If you want to use jsdoc/closure tag `@template`, you also need to specify this module as a plugin, like so:
If you want to use [supported ClosureCompiler features](#supported-closurecompiler-features), you also need to specify this module as a pluginin your JSON configuration, like so:

```json
{
Expand Down Expand Up @@ -101,16 +101,16 @@ the code are ignored. These are:

All other JSDoc tags should work fine.

## Supported ClosureCompiler Tags
## Supported ClosureCompiler features

ClosureCompiler has a couple tags beyond the built-in JSDoc tags that can improve your TypeScript output. Here is a complete
list of the tags from CC that are supported in this template:
list of the features from CC that are supported in this template:

- [`@template`](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#template-t) - For generics
- [`@template T`](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#template-t) - For generics
- [`typeof T`](https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System#the-javascript-type-language) - For typeof operator

## Extended support for TS features
## Supported non-standard features

JSDoc doesn't have a way to express all the features of typescript so we treat some syntax as special case to
create better Typescript.
Vanilla JSDoc doesn't have a way to express all the features of TypeScript so we also support these non-standardized conventions:

- `Class<T>` - If we encounter a type that is `Class<T>` we will treat it as `typeof T`. See [jsdoc3/jsdoc#1349](https://github.com/jsdoc3/jsdoc/issues/1349)
14 changes: 14 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,17 @@ export function defineTags(dictionary: ITagDictionary) {
}
});
};

const regexTypeOf = /typeof\s+([^\|\}]+)/g

export var handlers = {
jsdocCommentFound: function(event: { filename?: string; comment?: string; lineno?: number; }) {
let oldResult = "";
let newResult = event.comment || "";
while (newResult !== oldResult) {
oldResult = newResult;
newResult = newResult.replace(regexTypeOf, (typeExpression, className) => "Class<" + className + ">");
}
event.comment = newResult;
}
};
23 changes: 23 additions & 0 deletions test/expected/typeof_all.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
declare class Foobar1 {
x: typeof MyClass;
y: typeof MyClass;
z: string | typeof MyClass;
u: typeof MyClass | string;
v: (typeof MyClass)[];
w: typeof Array;
q: typeof Array;
r: typeof Class;
s: typeof Array;
}

declare class Foobar2 {
x: typeof MyClass;
y: typeof MyClass;
z: string | typeof MyClass;
u: typeof MyClass | string;
v: (typeof MyClass)[];
w: typeof Array;
q: typeof Array;
r: typeof Class;
s: typeof Array;
}
25 changes: 25 additions & 0 deletions test/fixtures/typeof_all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @property {Class<MyClass>} x
* @property {Class.< MyClass >} y
* @property {string|Class<MyClass>} z
* @property {Class<MyClass>|string} u
* @property {Array<Class<MyClass>>} v
* @property {Class<Array<MyClass>>} w
* @property {Class<MyClass[]>} q
* @property {Class<Class<MyClass>>} r
* @property {Class<Array<Class<MyClass>>>} s
*/
class Foobar1 {}

/**
* @property {typeof MyClass} x
* @property {typeof MyClass } y
* @property {string|typeof MyClass} z
* @property {typeof MyClass|string} u
* @property {Array<typeof MyClass>} v
* @property {typeof Array<MyClass>} w
* @property {typeof MyClass[]} q
* @property {typeof typeof MyClass} r
* @property {typeof Array<typeof MyClass>} s
*/
class Foobar2 {}
7 changes: 7 additions & 0 deletions test/specs/typeof.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { expectJsDoc } from '../lib';

suite('Typeof Checks', () => {
test('All', () => {
expectJsDoc('typeof_all');
});
});

0 comments on commit fe18a88

Please sign in to comment.