summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/types/README.md
blob: ebd01dec6090a61b023c8d368ba7f9ad31e16f39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# PoC Type-Checking JavaScript Using JSDocs

## Intro

TypeScript can be used on plain JavaScript files documented with JSDoc comments
to check types without a build step.  This is a proof of concept to show
viability and benefits of doing this for a "typical" component.

* [Handbook: Type Checking JavaScript Files][handbook]
* [JSDoc Reference][jsdoc]

## New files

 * `tsconfig.json`: at the root of a TypeScript "project" configures how to find
   and check files.

 * `types/globals.ts`: defines available globals, types and various utilities.

 * `types/XPCShellContentUtils.sys.mts`: an example of type definitions file for
   an external module which was automatically generated by `tsc`.

## How to use and expectations

Use [npm or yarn to install][download] TypeScript.
Then run `tsc` in the extensions directory to check types:

```
mozilla-central/toolkit/components/extensions $ tsc
```

You can also use an editor which supports the [language server][langserv].
VSCode should pick it up automatically, but others like Vim might need
[some configuring][nvim].

Other than continuing to use JSDocs, trying to follow guidelines below, and
hopefully remembering to run `tsc` occasionally, for now there is explicitly
*no expectation* that all new code must be fully typed, or pass typecheck
on every commit.

If you are in a hurry, or run into a confusing type problem, feel free to
slap a @ts-ignore and/or ask for help from someone more familiar. Hopefully
as workflow gets better integrations, we all learn some typescript along
the way, and the whole process remains non-disruptive.

## Guidelines for type-friendly code

Using more modern and idiomatic code patterns can enable better type inference
by the TypeScript compiler.

These fall under 5 main categories:

 1) Declare and/or initialize all class fields in the constructor.
    * (general good practice)

 2) Use real getters and redefineGetter instead of defineLazyGetter.
    * (also keeps related code closer together)

 3) When extending, don't override class fields with getters, or vice versa.
    * https://github.com/microsoft/TypeScript/pull/33509

 4) Declare and assign object literals at the same time, not separately.
    * (don't use `let foo;` at the top of the file, use `var foo = {`)

 5) Don't re-use local variables unnecessarily with different types.
    * (general good practice, local variables are "free")

### @ts-ignore recommendations

*Don't* use `@ts-ignore` for class fields and function or method signatures.

*Feel free* to use it:
 * locally inside methods,
 * when the alternative is more noise than signal,
 * when doing so isn't preventing passthrough of type-inference through other
   parts of the codebase.


[handbook]: https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html

[jsdoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html

[download]: https://www.typescriptlang.org/download

[langserv]: https://github.com/typescript-language-server/typescript-language-server

[nvim]: https://www.reddit.com/r/neovim/comments/131l9cw/theres_another_typescript_lsp_that_wraps_the/