Skip to content

Commit 20d34b5

Browse files
authored
Update JS documentation in CHANGES.md: (#3718)
1 parent ee4225a commit 20d34b5

1 file changed

Lines changed: 62 additions & 49 deletions

File tree

CHANGES.md

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ For example, Corsa uses the same rule for checking calls in both TypeScript and
88
And because Corsa uses the same rule for optional parameters, it fixes subtle Strada bugs with `"strict": true` in JavaScript.
99

1010
We primarily want to support people writing modern JavaScript, using things like ES modules, classes, destructuring, etc.
11-
Not CommonJS modules and constructor functions, although those do still work.
12-
However, we have trimmed a lot of unused or underused features.
11+
To that end, we have trimmed a lot of unused or underused features.
1312
This makes the implementation much simpler and more like TypeScript.
1413

1514
The biggest single removed area is support for Closure header files--most Closure-specific features, in fact.
@@ -28,6 +27,26 @@ function f() {}
2827
f.called = false;
2928
```
3029

30+
One important use of expando declarations is no longer supported: constructor functions.
31+
32+
```js
33+
function C() {
34+
this.property = 1;
35+
}
36+
C.prototype.method = function() {}
37+
```
38+
39+
Use classes instead:
40+
41+
```js
42+
class C {
43+
constructor() {
44+
this.property = 1;
45+
}
46+
method() {}
47+
}
48+
```
49+
3150
## Declaration Emit
3251

3352
We've fundamentally rewritten core parts of the declaration emit *and* JavaScript parsing components.
@@ -46,11 +65,8 @@ However, if you see **_incorrect_** `.d.ts` output from a `.js` file, **please f
4665
| UnknownType | `?` | `any` | |
4766
| NamepathType | `Module:file~id` | `import("file").id` | TS has never had semantics for this. |
4867
| `@class` | <pre><code>/** @class */</code><br/><code>function C() {</code><br/> <code>this.p = 1;</code><br/><code>}</code></pre> | <pre><code>class C {</code><br/><code> constructor() {</code><br/><code> this.p = 1;</code><br/><code> }</code><br/><code>}</code></pre> | Use regular `class` declarations. |
49-
| `@throws` | <pre><code>/** @throws {E} */</pre></code> | Keep the same. | TS never had semantics for this. |
5068
| `@enum` | <pre><code>/\** @enum {number} */</code><br/><code>const E = { A: 1, B: 2 };</code></pre> | <pre><code>/** @typedef {number} E \*/</code><br/><code>/** @type {Record<string, E>} */</code><br/><code>const E = { A: 1, B: 2 };</code></pre> | Closure feature. |
5169
| `@author` | <pre><code>/** @author Finn <finn@treehouse.com> */</pre></code> | Keep the same. | `@treehouse` parses as a new tag in Corsa. |
52-
| Postfix optional type | `T?` | `T \| undefined` | This was legacy in Closure. |
53-
| Postfix definite type | `T!` | `T` | This was legacy in Closure. |
5470
| Identifier-named typedefs |<pre><code>`/** @typedef {T} */ typeName;</pre></code> | <pre><code>/** @typedef {T} typeName */</pre></code> | Closure feature. |
5571
| Closure function type syntax | <pre><code>/* @type {function(string): void} */</pre></code> | <pre><code>/* @type {(s: string) => void} */</pre></code> | |
5672
| Automatic typeof insertion | <pre><code>const o = { a: 1 };</code><br/><code>/\** @type {o} */</code><br/><code>var o2 = { a: 1 };</code></pre> | <pre><code>const o = { a: 1 };</code><br/><code>/\** @type {typeof o} */</code><br/><code>var o2 = { a: 1 };</code></pre> | |
@@ -60,10 +76,9 @@ However, if you see **_incorrect_** `.d.ts` output from a `.js` file, **please f
6076

6177
| Name | Example | Substitute | Note |
6278
| -------------------------- | ------- | ----------- |----- |
79+
| Constructor functions | <pre><code>function C() {</code><br/><code> this.p = 1;</code><br/><code>}</code><br/><code>C.prototype.m = function() { };</code></pre> | <pre><code>class C {</code><br/><code> p = 1;</code><br/><code> m() { }</code><br/><code>}</code></pre> | Use regular `class` declarations. |
6380
| Fallback initialisers | <pre><code>f.x = f.x \|\| init;</pre></code> | <pre><code>if (!f.x) f.x = init;</pre></code> | |
6481
| Nested, undeclared expandos | <pre><code>var N = {};</code><br/><code>N.X.Y = {};</code></pre> | <pre><code>var N = {};</code><br/><code>N.X = {};</code><br/><code>N.X.Y = {};</code></pre> | All intermediate expandos have to be assigned. Closure feature. |
65-
| Constructor function prototype assignment | <pre><code>function C() { }</code><br><code>C.prototype.m = function() { };</code></pre> | <pre><code>class C {</code><br><code> m() { }</code><br/><code>}</code></pre> | Use regular `class` declarations. |
66-
| Constructor function prototype assignment | <pre><code>function C() { }</code><br><code>C.prototype = {</code><br/> <code>m: function() { }</code><br/><code>};</code></pre> | <pre><code>class C {</code><br><code> m() { }</code><br/><code>}</code></pre> | Use regular `class` declarations. |
6782
| Identifier declarations | <pre><code>class C {</code><br/> <code>constructor() {</code><br/> <code>/\** @type {T} */</code><br/> <code>this.identifier;</code><br/> <code>}</code><br/><code>}</code></pre> | <pre><code>class C {</code><br/> <code>/\** @type {T} */</code><br/> <code>identifier;</code><br/> <code>constructor() { }</code><br/><code>}</code></pre> | Closure feature. |
6883
| `this` aliases | <pre><code>class C() {</code><br/><code> constructor() {</code><br><code> var that = this;</code><br/><code> that.x = 12;</code><br/><code> }</code><br><code>}</code></pre> | <pre><code>class C() {</code><br/><code> constructor() {</code><br><code> this.x = 12;</code><br/><code> }</code><br><code>}</code></pre> | |
6984
| `this` alias for `globalThis` | <pre><code>this.globby = true;</pre></code> | <pre><code>globalThis.globby = true;</pre></code> | When used at the top level of a script. |
@@ -98,17 +113,15 @@ However, if you see **_incorrect_** `.d.ts` output from a `.js` file, **please f
98113

99114
JSDoc types are parsed in normal type annotation position but show a grammar error. Corsa no longer parses the JSDoc types below, giving a parse error instead of a grammar error.
100115

101-
1. No postfix `T?` and `T!` types. Prefix `?T` and `!T` are still parsed and `!T` continues to have no semantics.
102-
2. No Closure `function(string,string): void` types.
103-
3. No JSDoc standalone `?` type.
104-
4. No JSDoc module namepaths: `module:folder/file.C`
116+
1. No Closure `function(string,string): void` types.
117+
2. No JSDoc standalone `?` type.
118+
3. No JSDoc module namepaths: `module:folder/file.C`
105119

106120
Corsa no longer parses the following JSDoc tags with a specific node type. They now parse as generic JSDocTag nodes.
107121

108122
1. `@class`/`@constructor`
109-
2. `@throws`
110-
3. `@author`
111-
4. `@enum`
123+
2. `@author`
124+
3. `@enum`
112125

113126
## Checker
114127

@@ -234,7 +247,7 @@ This means the declarations are accessible outside the class and may conflict wi
234247

235248
#### `@class` or `@constructor` does not make a function into a constructor function.
236249

237-
Corsa ignores `@class` and `@constructor`. This makes a difference on a function without this-property assignments or associated prototype-function assignments.
250+
Constructor functions are no longer supported. See the Expandos section.
238251

239252
#### `@param` tags now apply to at most one function.
240253

@@ -263,6 +276,40 @@ In Corsa, the behaviour is the same between TS and JS.
263276

264277
### Expandos
265278

279+
#### Constructor functions are no longer supported
280+
281+
Previously, you could create a constructor function either by assigning an expando property in the constructor, or an expando property to the function's prototype:
282+
283+
```js
284+
function C() {
285+
this.property = 1;
286+
}
287+
C.prototype.method = function() {}
288+
```
289+
290+
Less common patterns, like assigning an object literal to the prototype, also need to be rewritten to use standard class syntax:
291+
292+
```js
293+
function Foo() {}
294+
Foo.prototype = {
295+
/** @param {number} x */
296+
bar(x) {
297+
return x;
298+
},
299+
};
300+
```
301+
302+
Classes are a much better way to write this code:
303+
304+
```js
305+
class Foo {
306+
/** @param {number} x */
307+
bar(x) {
308+
return x;
309+
}
310+
}
311+
```
312+
266313
#### Expando assignments of `void 0` are no longer ignored as a special case:
267314

268315
```js
@@ -298,42 +345,8 @@ class SharedClass2 {
298345
}
299346
```
300347

301-
#### Assigning to the `prototype` property of a function no longer makes it a constructor function:
302-
303-
```js
304-
function Foo() {}
305-
Foo.prototype = {
306-
/** @param {number} x */
307-
bar(x) {
308-
return x;
309-
},
310-
};
311-
```
312-
313-
Classes are a much better way to write this code.
314-
315-
```js
316-
class Foo {
317-
/** @param {number} x */
318-
bar(x) {
319-
return x;
320-
}
321-
}
322-
```
323-
324348
### CommonJS
325349

326-
#### Initializing exports to `undefined`:
327-
328-
To accommodate the pattern of initializing CommonJS exports to `undefined` (sometimes written as `void 0`) and then subsequently assigning their intended values, when CommonJS exports have multiple assignments and an initial assignment of `undefined`, the `undefined` is ignored when determining the type of the export.
329-
330-
```js
331-
exports.foo = exports.bar = void 0;
332-
// Later in the same file...
333-
exports.foo = 123 // Exported type is `123`
334-
exports.bar = "abc" // Exported type is `"abc"`
335-
```
336-
337350
#### Mixing module.exports assignments
338351

339352
Corsa does not permit CommonJS modules to mix assignments to the full `module.exports` with assignments to `module.exports.xxx` properties. A CommonJS module must either contain an assignment to `module.exports` or a series of assignments to `module.exports.xxx` properties, but not both.

0 commit comments

Comments
 (0)