tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 33844f242e53e50e1dde2a0258e4faa303ccf423
parent 58ae5b2ad37a45d4edb1245fe810d3a0b942b3bc
Author: Mark Banner <standard8@mozilla.com>
Date:   Sat, 22 Nov 2025 15:56:12 +0000

Bug 1975521 - Add initial documentation for TypeScript. r=frontend-codestyle-reviewers,mossop

Differential Revision: https://phabricator.services.mozilla.com/D268571

Diffstat:
Mdocs/code-quality/index.rst | 1+
Mdocs/code-quality/lint/linters/typescript.rst | 4++--
Adocs/code-quality/typescript/bestPractices.md | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/code-quality/typescript/index.md | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/code-quality/typescript/updatingTypes.md | 26++++++++++++++++++++++++++
5 files changed, 279 insertions(+), 2 deletions(-)

diff --git a/docs/code-quality/index.rst b/docs/code-quality/index.rst @@ -13,6 +13,7 @@ In this document, we try to list these all tools. static-analysis/index.rst lint/index.rst coding-style/index.rst + typescript/index.md .. list-table:: C/C++ :header-rows: 1 diff --git a/docs/code-quality/lint/linters/typescript.rst b/docs/code-quality/lint/linters/typescript.rst @@ -4,8 +4,7 @@ TypeScript `TypeScript`__ is being used as a type checker for JavaScript. This is a new linter that is being set up and readied for production use. Please -discuss with `Mark Banner (standard8) <https://people.mozilla.org/s?query=standard8>`__ -before setting up new projects. +see `this page`_ before setting up new projects. Run Locally ----------- @@ -68,4 +67,5 @@ For test harness issues, file bugs in Developer Infrastructure :: Lint and Forma .. __: https://www.typescriptlang.org/ +.. _this page: ../../typescript/index.html .. _Usage guide: ../usage.html diff --git a/docs/code-quality/typescript/bestPractices.md b/docs/code-quality/typescript/bestPractices.md @@ -0,0 +1,164 @@ +# Best Practices + +* [Enable JSDoc Linting](#enable-jsdoc-linting) +* [Documenting Types](#documenting-types) + * [Avoid Missing Type Annotations](#avoid-missing-type-annotations) + * [Variables](#variables) + * [Avoid object types](#avoid-object-types) + * [Import Types from Other Files](#import-types-from-other-files) +* [XPCOMUtils.declareLazy / defineLazy](#xpcomutilsdeclarelazy--definelazy) + +## Enable JSDoc Linting +ESLint supports linting of JSDoc comments. Enabling the rules on your component +will help to ensure that you avoid missing or incorrect type definitions for function parameters. + +You can check if your component is already covered by ensuring it is not in the +`rollout-valid-jsdoc` or `rollout-require-jsdoc` sections of the +[eslint-rollouts.config.mjs](https://searchfox.org/firefox-main/source/eslint-rollouts.config.mjs) +file in the top level of `firefox-main`. + +## Documenting Types + +### Avoid Missing Type Annotations +By default, if no type annotation is given and it cannot be inferred, then +TypeScript will assign that variable the `any` type. This is a special type that +skips type checking, and therefore may cause hidden failures. + +For class members and functions this means adding type definitions for all the +parameters, e.g. + +```js +class Foo { + /** + * Stores the search string. The type here could be omitted if the property is assigned in + * the constructor of the class. + * + * @type {string} + */ + #search; + + /** + * Details about the function. + * + * @param {string} searchString + * Param documentation. + * @param {object} previousResult + * Param documentation. + * @param {nsIAutoCompleteObserver} listener + * Param documentation. + */ + startSearch(searchString, previousResult, listener) {} +} +``` + +### Variables +Variable types will be inferred from the item that they are initially assigned +to. However, sometimes you may need to define the type appropriately, especially +for sets and maps. + +```js +// This will be inferred as type string. +let foo = "bar"; + +// This needs the type defining. +/** @type {Map<string, number>} */ +let baz = new Map(); +baz.set("star", 1701); +``` + +### Avoid object types +`object` types are treated much the same as `any` - there is no type checking +performed on them. + +Ideally all types should be defined. There are two ways to do this. + +The first is within JSDoc comments: + +```js +/** + * @typedef {object} submissionMapEntry + * @property {SearchEngine} engine + * The search engine. + * @property {string} termsParameterName + * The search term parameter name. + */ + +/** + * Alternately for function parameters: + * + * @param {object} options + * @param {boolean} options.option1 + * A required boolean property within options. + * @param {number} [options.option2] + * An optional number property within options. + */ +function myFunc(options) {} +``` + +This may then be used within the file. + +The second way may be more appropriate if a type is used widely within a +component. You can create a `types/urlbarType.d.ts` file, reference it from the +`tsconfig.json` file and include a definition such as: + +```js +/** + * A structure that holds the details of commands for results. + */ +type UrlbarResultCommand = { + /** + * The name of the command. Must be specified unless `children` is present. + * When a command is picked, its name will be passed as `details.selType` to + * `onEngagement()`. The special name "separator" will create a menu separator. + */ + name?: string; + /** + * An l10n object for the command's label. Must be specified unless `name` + * is "separator". + */ + l10n?: L10nIdArgs; + /** + * If specified, a submenu will be created with the given child commands. + */ + children?: UrlbarResultCommand[]; +}; +``` + +:::{note} +If you are sharing object types outside of your component, prefer using a proper +class definition or other structure. +::: + +### Import Types from Other Files + +You may import types from other files to be able to reuse them. + +```js +/** + * @import { LangTags } from "./translations.d.ts" + */ + +/** + * @import { OpenedConnection } from "resource://gre/modules/Sqlite.sys.mjs" + */ +``` + +A `*.d.ts` file is a special type-definition file for TypeScript. These should +generally only be used for types that are internal to your component and are +not exposed outside. + +## XPCOMUtils.declareLazy / defineLazy + +These are newer functions that combine the existing +[XPCOMUtils](https://searchfox.org/firefox-main/source/js/xpconnect/loader/XPCOMUtils.sys.mjs) +functions into formats that are compatible with TypeScript. + +Defining lazy objects with these functions provides the appropriate information +for TypeScript to be able to know the types on the lazy objects. Otherwise the +lazy objects will be defined as `any`. + +:::{note} +It is suggested that these are not generally used until the functions have been +[moved to ChromeUtils](https://bugzilla.mozilla.org/show_bug.cgi?id=1992437), +to avoid needing to import `XPCOMUtils` everywhere. +::: diff --git a/docs/code-quality/typescript/index.md b/docs/code-quality/typescript/index.md @@ -0,0 +1,86 @@ +# TypeScript +In firefox-main, we are introducing the use of [TypeScript](https://www.typescriptlang.org/) +to help provide type autocompletion, static analysis and type checking of our +JavaScript code. + +:::{note} +At the moment we are in the bootstrap/experimentation phase, there are various +parts of infrastructure that have not yet been created, and incomplete type +definitions which may cause issues for projects. Hence TypeScript is not +recommended for all projects for the time being. + +We are currently prioritising enabling type autocompletion across the code base, +before we proceed to more work on type checking. + +You can work towards enabling TypeScript by ensuring your code passes the +[ESLint jsdoc rules](https://searchfox.org/firefox-main/search?q=jsdoc%2F&path=eslint-plugin-mozilla%2Flib%2Fconfigs&case=false&regexp=false). + +If you are interested, please ask in the Lint and Formatting channel (#lint:mozilla.org) +on Matrix. +::: + +## Where TypeScript is Currently Enabled + +TypeScript is currently only enabled on a [limited set of directories](https://searchfox.org/firefox-main/source/tools/lint/typescript.yml). + +## Editor Support +VS Code has TypeScript support built-in and should work "out of the box". + +For other editors, see this [TypeScript Wiki Page](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support). + +## Running TypeScript Locally + +The TypeScript linter may be run on the directories where it is enabled using: + +``` +./mach lint -l typescript path/to/file # (or to the directory) +``` + +## Updating Gecko Type Definitions + +Updating types currently happens manually, although [we are in the process of +automating it](https://bugzilla.mozilla.org/show_bug.cgi?id=1975513). + +In the meantime, developers using TypeScript must update the type definitions +[manually using some scripts](updatingTypes.md). + +## Frequently Asked Questions + +* Why does running TypeScript check and report errors in other files? + * Changes in one file may impact on another, and TypeScript can detect this. + * Additionally, the way that TypeScript works means that it will run across + the whole project regardless, so we report all the issues that it reports. +* Will my patches get backed out due to TypeScript failures? + * Currently no. Whilst we have a [TypeScript Linter on CI](../lint/linters/typescript.rst) + it is currently tier-3 which is hidden from the sheriffs view. + * Failures will however, be reported on reviews on Phabricator. + * We will promote the linter to tier-2 and tier-1 once we have more automation + in place for type generation. +* Why isn't this being encouraged for everyone? + * As discussed in the note at the top of the page, we are still in the set-up + and experimentation phase. There is a lot of infrastructure that is required + to make TypeScript usable on a day to day basis. +* Are we planning to allow using TypeScript files and compiling directly from + TypeScript? + * No. In the past we've worked to avoid processing or compilation steps, + wherever possible when developing JavaScript. This helps to reduce code-test + cycle times and make debugging simpler. + * Whilst it is possible we could change the approach in future, it is not an + objective of enabling TypeScript over the firefox-main code base. +* Something isn't working as I would expect, where should I look/ask? + * We have a [meta bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1945456) + for TypeScript issues in firefox-main. We work through them over time, though + we appreciate help as well. + * See the [Getting Help](#getting-help) section. + +## Getting Help + +The Lint & Formatting channel (#lint:mozilla.org) on Matrix is the best place + to ask questions. + +## Further Reading + +* The [TypeScript documentation](https://www.typescriptlang.org/docs/) is very + useful in understanding how TypeScript works and how types may be set up. + * The [JavaScript section starting here](https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html), + is especially useful for firefox-main development. diff --git a/docs/code-quality/typescript/updatingTypes.md b/docs/code-quality/typescript/updatingTypes.md @@ -0,0 +1,26 @@ +# Updating Gecko Type Definitions + +The type definitions live in [tools/@types](https://searchfox.org/firefox-main/source/tools/@types), +with the generation scripts in [tools/ts](https://searchfox.org/firefox-main/source/tools/ts). + +## Updating JavaScript Module Paths + +The path maps are currently used for locating the sources of files referenced by +the `moz-src://`, `resource://` and `chrome://` uris. When files are added or +removed, these may need to be updated. + +```shell +$ ./mach ts paths +``` + +## Updating Gecko Types + +The Gecko types are updated from the source directory and build output. + +:::{warning} +A full build is required. +::: + +```shell +$ ./mach build && ./mach ts build && ./mach ts update +```