Skip to content

Commit b489124

Browse files
committed
Scribbles on JS differences
1 parent 174503f commit b489124

File tree

1 file changed

+62
-9
lines changed

1 file changed

+62
-9
lines changed

Type-Checking-JavaScript-Files.md

+62-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
TypeScript 2.3 and later support a mode of type-checking and reporting errors in `.js` files with `--checkJs`.
1+
TypeScript 2.3 and later support type-checking and reporting errors in `.js` files with `--checkJs`.
22

3-
You can skip checking some files by adding `// @ts-nocheck` comment to them; conversely you can choose to check only a few `.js` files by adding `// @ts-check` comment to them without setting `--checkJs`.
3+
You can skip checking some files by adding `// @ts-nocheck` comment to them; conversely, you can choose to check only a few `.js` files by adding a `// @ts-check` comment to them without setting `--checkJs`.
44
You can also ignore errors on specific lines by adding `// @ts-ignore` on the preceding line.
55

66
Here are some notable differences on how checking work in `.js` file from `.ts` file:
@@ -9,6 +9,8 @@ Here are some notable differences on how checking work in `.js` file from `.ts`
99

1010
In a `.js` file, types can often be inferred just like in `.ts` files.
1111
Likewise, when types can't be inferred, they can be specified using JSDoc the same way that type annotations do in a `.ts` file.
12+
Just like Typescript, `--noImplicitAny` will give you errors on the places that the compiler could not infer a type.
13+
(With the exception of open-ended object literals; see below for details.)
1214

1315
JSDoc annotations adorning a declaration will be used to set the type of that declaration. For example:
1416

@@ -22,46 +24,96 @@ x = false; // Error: boolean is not assignable to number
2224

2325
You can find the full list of supported JSDoc patterns in the [JSDoc support in JavaScript documentation](https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript).
2426

27+
2528
## Property declaration inferred from assignments in class bodies
2629

2730
ES2015/ES6 does not have a means for declaring properties on classes. Properties are dynamically assigned, just like in the case of object literals.
2831

29-
In a `.js` file property declarations are inferred from assignments to the properties inside the class body. The type of properties is the union of the types of all the right-hand values in these assignments. Properties defined in the constructor are always assumed to exist, where as ones defined in methods, getters, or setters are considered optional.
32+
In a `.js` file, property declarations are inferred from assignments to the properties inside the class body.
33+
The type of properties is the type given in the constructor, unless it's not defined there, or the type in the constructor is undefined or null.
34+
In that case, the type is the union of the types of all the right-hand values in these assignments.
35+
Properties defined in the constructor are always assumed to exist, where as ones defined just in methods, getters, or setters are considered optional.
36+
37+
```js
38+
class C {
39+
constructor() {
40+
this.x = 0
41+
}
42+
method() {
43+
this.x = false // error, x is a number
44+
this.y = 'ok' // ok, but y could also be undefined
45+
}
46+
method2() {
47+
this.y = true // also, ok, y's type is string | boolean | undefined
48+
}
49+
}
50+
```
3051

31-
Adorn property assignments with JSDoc to specify the type of the property as needed. For instance:
52+
If the property type can't be inferred, annotate the assignment in the constructor with JSDoc to specify the type.
53+
You don't even have to give a value if it will be initialised later:
3254

3355
```js
3456
class C {
3557
constructor() {
3658
/** @type {number | undefined} */
3759
this.prop = undefined;
38-
60+
/** @type {number | undefined} */
61+
this.count;
3962
}
4063
}
4164

4265

4366
let c = new C();
4467
c.prop = 0; // OK
45-
c.prop = "string"; // Error: string is not assignable to number|undefined
68+
c.count = "string"; // Error: string is not assignable to number|undefined
4669
```
4770

4871
If properties are never set in the class body, they are considered unknown. If your class has properties that are only read from, consider adding an initialization in the constructor to undefined, e.g. `this.prop = undefined;`.
4972

73+
## null/undefined/[] initializers are of type any or any[]
74+
75+
Any variable, parameter or property that is initialized with null or undefined will have type any, even if strict null checks is turned on.
76+
Any variable, parameter or property that is initialized with [] will have type any[], even if strict null checks is turned on.
77+
The only exception is for properties that have multiple initializers as described above.
78+
79+
## Constructor functions work basically the same as classes
80+
81+
Right down to methods. Lots of detail needs to go here. Kind of surprised there was none.
82+
83+
## Many things are namespaces now
84+
85+
Constructor functions are namespaces:
86+
87+
```js
88+
function Outer() {
89+
this.y = 2
90+
}
91+
Outer.Inner = class {
92+
}
93+
```
94+
95+
TODO: Other kinds of initializers
96+
97+
TODO: Much more
98+
5099
## CommonJS module input support
51100

52101
In a `.js` files CommonJS module format is allowed as an input module format. Assignments to `exports`, and `module.exports` are recognized as export declarations. Similarly, `require` function calls are recognized as module imports. For example:
53102

54-
```ts
55-
// import module "fs"
103+
```js
104+
// same as `import module "fs"`
56105
const fs = require("fs");
57106

58107

59-
// export function readFile
108+
// same as `export function readFile`
60109
module.exports.readFile = function(f) {
61110
return fs.readFileSync(f);
62111
}
63112
```
64113

114+
The module support in Javascript is much more syntactically forgiving than Typescript's module support.
115+
Most combinations of assignments and declarations are supported.
116+
65117
## Object literals are open-ended
66118

67119
By default object literals in variable declarations provide the type of a declaration. No new members can be added that were not specified in the original initialization. This rule is relaxed in a `.js` file; object literals have an open-ended type, allowing adding and looking up properties that were not defined originally. For instance:
@@ -120,6 +172,7 @@ sayHello();
120172

121173
A function whose body has a reference to the `arguments` reference is implicitly considered to have a var-arg parameter (i.e. `(...arg: any[]) => any`). Use JSDoc var-arg syntax to specify the type of the arguments.
122174

175+
TODO: Give an example of the correct jsdoc
123176

124177
## Unspecified type parameters default to `any`
125178

0 commit comments

Comments
 (0)