# Quick Lint Js > The following contributors are copyright holders of portions of quick-lint-js: --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/AUTHORS.md # quick-lint-js authors ## Copyright holders The following contributors are copyright holders of portions of quick-lint-js: ### Major copyright holders * Matthew "strager" Glazar; strager.nds@gmail.com ### Minor copyright holders * CodeItQuick; evanontario@hotmail.com * EdTheDagger * Tom * david doroz; dd8788@rit.edu * spicyyboi ## Authors In addition to the copyright holders listed above, the following contributors authored portions of quick-lint-js: * A-thanasios; https://github.com/A-thanasios; signed CLA-v1.md * AidenThing; signed CLA-v1.md * Alek Lefebvre; alek.lefebvre@gmail.com; signed CLA-v1.md * Alessandro De Bellis; aledeb95@gmail.com; signed CLA-v1.md * Alex Via; alexviacoll@gmail.com; signed CLA-v1.md * Amir; amir77mafi@gmail.com; signed CLA-v1.md * Ang Kosal; angkosal@gmail.com; signed CLA-v1.md * Angel Avila; angel.j.avila@gmail.com; signed CLA-v1.md * Ariel Don; ariel@arieldon.com; signed CLA-v1.md * Asaduzzaman Pavel; k1ngs.k1ngdom@live.com; signed CLA-v1.md * Austin Garcia; theholychowders@gmail.com; signed CLA-v1.md * Biel A. P. (0xbiel); bielp07@gmail.com; signed CLA-v1.md * Brandon Conway; brandoncc@gmail.com; signed CLA-v1.md * Carlo Cabrera; https://github.com/carlocab; signed CLA-v1.md * Christopher M Stoddard; https://github.com/cmstoddard; signed CLA-v1.md * CoderMuffin; john@mooseandlemur.com; signed CLA-v1.md * Cuong Do; cuong7dovan@gmail.com; signed CLA-v1.md * Daniel La Rocque; dlarocque.contact@gmail.com; signed CLA-v1.md * David Vasileff; signed CLA-v1.md * Dylan Elliott; signed CLA-v1.md * Erlliam Mejia; tommejas@gmail.com; signed CLA-v1.md * Francis Laniel; signed CLA-v1.md * Frank Buss; fb@frank-buss.de; signed CLA-v1.md * Guilherme Vasconcelos; signed CLA-v1.md * Harshit Aghera; signed CLA-v1.md * Himanshu; himansingh24@gmail.com; signed CLA-v1.md * Isaac Nonato; nonatoisaac@mailfence.com; signed CLA-v1.md * Jait Jacob; jai8.jacob@gmail.com; signed CLA-v1.md * James Moles; jamespmoles@gmail.com; signed CLA-v1.md * Jan Poonthong; janpoonthong628@gmail.com; signed CLA-v1.md * Jenny "Jennipuff" Wheat * Jesus Gil; jesusgil.dev@gmail.com; signed CLA-v1.md * Jesús Eduardo; jeduardo.fuentes@alumnos.udg.mx; signed CLA-v1.md * Jimmy Qiu; bottlewater072@gmail.com; signed CLA-v1.md * Joshua Pepple; pepplejoshuatams@gmail.com; signed CLA-v1.md * Justin Welenofsky; welenofsky@gmail.com; signed CLA-v1.md * Kate Conkright; conkrigh@umich.edu; signed CLA-v1.md * Kim "Linden"; kim.lindbla@gmail.com; signed CLA-v1.md * Lee Wannacott; wannacottL@gmail.com; signed CLA-v1.md * Leszek Nowicki; nowickileszek88@gmail.com; signed CLA-v1.md * LiraNuna; signed CLA-v1.md * Matheus Phranco; matheusphranco@gmail.com; signed CLA-v1.md * Matheus Sousa; msamuel@aluno.puc-rio.br; signed CLA-v1.md * Max 👨🏽‍💻 Coplan; mchcopl@gmail.com; signed CLA-v1.md * Menotdan; mrcobalt124@gmail.com; signed CLA-v1.md * Ming Ng; signed CLA-v1.md * Mothi Ghimire; mothi.ghimire@gmail.com; signed CLA-v1.md * Nico Sonack; nsonack@outlook.com; signed CLA-v1.md * Peter Khalil; https://github.com/m5tfi; signed CLA-v1.md * Rebraws; nahuel.braian@gmail.com; signed CLA-v1.md * Rob Miner; robminer@umich.edu; signed CLA-v1.md * Roland Strasser; signed CLA-v1.md * Ross Barnie; r.barnie@gmail.com; signed CLA-v1.md * Rui Serra; ruipserra@gmail.com; signed CLA-v1.md * Samir Hamud; latander@gmail.com; signed CLA-v1.md * Sarah Schulte; sarah.schulte@samsara.com; signed CLA-v1.md * Sasha Krassovsky; warplane@hotmail.com; signed CLA-v1.md * Shivam Mehta; sm.cse17@gmail.com; signed CLA-v1.md * Tom Binford; tjbof123@gmail.com; signed CLA-v1.md * Tony Sathre; tony@ghostbit.org; signed CLA-v1.md * Valekh Bayramov; koopiehoop@gmail.com; signed CLA-v1.md * Yash Masani; yash.masani@gmail.com; signed CLA-v1.md * Youness Asserare; signed CLA-v1.md * Yunus; ynsmrycl2007@gmail.com; signed CLA-v1.md * alex-huff; alexanderhuff53@gmail.com; signed CLA-v1.md * andjimenezuf; signed CLA-v1.md * catac; https://github.com/catac1; signed CLA-v1.md * clegoz; signed CLA-v1.md * daethtech; https://github.com/daethtech; signed CLA-v1.md * emadflash; signed CLA-v1.md * msharipov; msharipovr@gmail.com; signed CLA-v1.md * ooblegork; codyxvalley@mail.fresnostate.edu; signed CLA-v1.md * oren; countoren@gmail.com; signed CLA-v1.md * pedrobl85; pedrobl1718@gmail.com; signed CLA-v1.md * toastino; toastino@disroot.org; signed CLA-v1.md * wagner riffel; w@104d.net; signed CLA-v1.md --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/CLA-v1.md # Contributor License Agreement This document is based on the Fiduciary License Agreement 2.0, based on the Individual Contributor Exclusive License Agreement (including the Traditional Patent License OPTION). Thank you for your interest in contributing to Matthew Glazar's quick-lint-js ("We" or "Us"). The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us. To make this document effective, please do any of the following: 1. Sign on a pull request: 1. Publish a GitHub Pull Request to [quick-lint/quick-lint-js](https://github.com/quick-lint/quick-lint-js). 2. In response to *CLA Assistant Lite bot*, publish a comment containing the following message exactly: "I have read and hereby agree to quick-lint-js' Contributor License Agreement (CLA-v1.md)." 2. Sign via email: 1. Send an email to [Matthew "strager" Glazar ](mailto:strager.nds@gmail.com) with your name, whether or not you want your email address to be public, and the following message exactly: "I have read and hereby agree to quick-lint-js' Contributor License Agreement (CLA-v1.md)." ## 0. Preamble Software is deeply embedded in all aspects of our lives and it is important that it empower, rather than restrict us. Free Software gives everybody the rights to use, understand, adapt and share software. These rights help support other fundamental freedoms like freedom of speech, press and privacy. Development of Free Software can follow many patterns. In some cases whole development is handled by a sole programmer or a small group of people. But usually, the creation and maintenance of software is a complex process that requires the contribution of many individuals. This also affects who owns the rights to the software. In the latter case, rights in software are owned jointly by a great number of individuals. To tackle this issue some projects require a full copyright assignment to be signed by all contributors. The problem with such assignments is that they often lack checks and balances that would protect the contributors from potential abuse of power from the new copyright holder. FSFE's Fiduciary License Agreement (FLA) was created by the Free Software Foundation Europe e.V. with just that in mind – to concentrate all deciding power within one entity and prevent fragmentation of rights on one hand, while on the other preventing that single entity from abusing its power. The main aim is to ensure that the software covered under the FLA will forever remain Free Software. This process only serves for the transfer of economic rights. So-called moral rights (e.g. authors right to be identified as author) remain with the original author(s) and are inalienable. ## How to use this FLA If You are an employee and have created the Contribution as part of your employment, You need to have Your employer approve this Agreement or sign the Entity version of this document. If You do not own the Copyright in the entire work of authorship, any other author of the Contribution should also sign this - in any event, please contact Us at [strager.nds@gmail.com](mailto:strager.nds@gmail.com). ## 1. Definitions "You" means the individual Copyright owner who Submits a Contribution to Us. "Contribution" means any original work of authorship, including any original modifications or additions to an existing work of authorship, Submitted by You to Us, in which You own the Copyright. "Copyright" means all rights protecting works of authorship, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence. "Material" means the software or documentation made available by Us to third parties. When this Agreement covers more than one software project, the Material means the software or documentation to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material. "Submit" means any act by which a Contribution is transferred to Us by You by means of tangible or intangible media, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us, but excluding any transfer that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." "Documentation" means any non-software portion of a Contribution. ## 2. License grant ### 2.1 Copyright license to Us Subject to the terms and conditions of this Agreement, You hereby grant to Us a worldwide, royalty-free, exclusive, perpetual and irrevocable (except as stated in Section 8.2) license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to: * publish the Contribution, * modify the Contribution, * prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials, * reproduce the Contribution in original or modified form, * distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form. ### 2.2 Moral rights Moral Rights remain unaffected to the extent they are recognized and not waivable by applicable law. Notwithstanding, You may add your name to the attribution mechanism customary used in the Materials you Contribute to, such as the header of the source code files of Your Contribution, and We will respect this attribution when using Your Contribution. ### 2.3 Copyright license back to You Upon such grant of rights to Us, We immediately grant to You a worldwide, royalty-free, non-exclusive, perpetual and irrevocable license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to: * publish the Contribution, * modify the Contribution, * prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials, * reproduce the Contribution in original or modified form, * distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form. This license back is limited to the Contribution and does not provide any rights to the Material. ## 3. Patents ### 3.1 Patent license Subject to the terms and conditions of this Agreement You hereby grant to Us and to recipients of Materials distributed by Us a worldwide, royalty-free, non-exclusive, perpetual and irrevocable (except as stated in Section 3.2) patent license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with any Material (and portions of such combination). This license applies to all patents owned or controlled by You, whether already acquired or hereafter acquired, that would be infringed by making, having made, using, selling, offering for sale, importing or otherwise transferring of Your Contribution(s) alone or by combination of Your Contribution(s) with any Material. ### 3.2 Revocation of patent license You reserve the right to revoke the patent license stated in section 3.1 if We make any infringement claim that is targeted at your Contribution and not asserted for a Defensive Purpose. An assertion of claims of the Patents shall be considered for a "Defensive Purpose" if the claims are asserted against an entity that has filed, maintained, threatened, or voluntarily participated in a patent infringement lawsuit against Us or any of Our licensees. ## 4. License obligations by Us We agree to (sub)license the Contribution or any Materials containing, based on or derived from your Contribution under the terms of any licenses the Free Software Foundation classifies as Free Software License and which are approved by the Open Source Initiative as Open Source licenses. More specifically and in strict accordance with the above paragraph, we agree to (sub)license the Contribution or any Materials containing, based on or derived from the Contribution only in accordance with our licensing policy available at: We agree to license patents owned or controlled by You only to the extent necessary to (sub)license Your Contribution(s) and the combination of Your Contribution(s) with the Material under the terms of any licenses the Free Software Foundation classifies as Free Software licenses and which are approved by the Open Source Initiative as Open Source licenses. ## 5. Disclaimer THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION AND EXTENT TO THE MINIMUM PERIOD AND EXTENT PERMITTED BY LAW. ## 6. Consequential damage waiver TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR WE BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. ## 7. Approximation of disclaimer and damage waiver IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 5. AND SECTION 6. CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE WAIVER OF ALL CIVIL OR CONTRACTUAL LIABILITY IN CONNECTION WITH THE CONTRIBUTION. ## 8. Term 8.1 This Agreement shall come into effect upon Your acceptance of the terms and conditions. 8.2 This Agreement shall apply for the term of the copyright and patents licensed here. However, You shall have the right to terminate the Agreement if We do not fulfill the obligations as set forth in Section 4. Such termination must be made in writing. 8.3 In the event of a termination of this Agreement Sections 5., 6., 7., 8., and 9. shall survive such termination and shall remain in full force thereafter. For the avoidance of doubt, Free and Open Source Software (sub)licenses that have already been granted for Contributions at the date of the termination shall remain in full force after the termination of this Agreement. ## 9. Miscellaneous 9.1 This Agreement and all disputes, claims, actions, suits or other proceedings arising out of this agreement or relating in any way to it shall be governed by the laws of United States of America excluding its private international law provisions. 9.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings. 9.3 In case of Your death, this agreement shall continue with Your heirs. In case of more than one heir, all heirs must exercise their rights through a commonly authorized person. 9.4 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and that is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law. 9.5 You agree to notify Us of any facts or circumstances of which you become aware that would make this Agreement inaccurate in any respect. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/CODE_SIGNING.md # Code-signing quick-lint-js In order to sign quick-lint-js, you need a code signing certificate. ## Creating a certificate You can create a self-signed certificate for local testing (but not distribution): 1. [Create a self-signed CA for code signing][macos-create-ca]. 2. [Create a certificate for code signing][macos-create-cert]. You will also need a GnuPG key. Generate one with an RSA key of at least 4096 bits. ## Creating signing files After creating a code signing certificate, you need to create files for signing. In the Keychain Access app, export your code signing certificate (not CA)'s public key as a .cer file. Call it `dist/certificates/quick-lint-js.cer`. Then, convert the `.cer` DER (binary) file into a `.crt` PEM (text) file by running the following command: $ openssl x509 -in dist/certificates/quick-lint-js.cer -inform der -out dist/certificates/quick-lint-js.crt After creating the `.crt` file, [update the macOS code signing requirements file][apple-csreq]. In the Keychain Access app, export your code signing certificate (not CA) and private key as a .p12 file. Call it `dist/certificates/quick-lint-js-PRIVATE.p12`. **Do not commit this file.** Then, convert the `.p12` file into an `.key` RSA key file by running the following command (**do not commit the `.key` file**): $ openssl pkcs12 -in dist/certificates/quick-lint-js-PRIVATE.p12 -nocerts -out /dev/stdout -passout pass:temporarypass | openssl rsa -in /dev/stdin -out dist/certificates/quick-lint-js-PRIVATE.key -passin pass:temporarypass To export the GnuPG key, run the following commands (**do not commit the `quick-lint-js-PRIVATE.gpg.key` file**): $ gpg --output dist/certificates/quick-lint-js.gpg.key --armor --export $YOUR_KEY_FINGERPRINT $ gpg --output dist/certificates/quick-lint-js-PRIVATE.gpg.key --export-secret-key $YOUR_KEY_FINGERPRINT ## Signing When you run the `dist/sign-release.go` program, specify `-RelicConfig dist/certificates/relic-config.yaml`. ## Updating production certificates After sacrificing a goat to the PKI gods by purchasing a signing certificate from a certificate authority (e.g. [SSL.com][]): 1. Open Keychain Access. 2. Right-click the private key. * Note: The production certificate is called "quick-lint-js" (RSA 4096-bit). 3. Choose "Request a Certificate From a Certificate Authority". 4. Fill in the Common Name (CN) based on the CN provided by your certificate authority. * Note: The production CN is "Matthew Glazar". 5. Give the CSR to your certificate authority. 6. Download the certificate chain .crt file, saving it to `dist/certificates/quick-lint-js.crt`. 7. Augment .crt file with certificates root CAs: * `SSL_COM_ROOT_CERTIFICATION_AUTHORITY_RSA.crt` 8. [Update the macOS code signing requirements file.][apple-csreq] [SSL.com]: https://www.ssl.com/ [macos-create-ca]: https://www.simplified.guide/macos/keychain-ca-code-signing-create [macos-create-cert]: https://www.simplified.guide/macos/keychain-cert-code-signing-create [apple-csreq]: ../dist/apple/README.md --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/FUZZING.md # Fuzz-testing quick-lint-js This document describes quick-lint-js' self fuzz-testing for contributors. Instructions in this document are written for Linux and macOS users. Fuzz-testing might work on Windows, but it hasn't been tested. ## libFuzzer-based tests quick-lint-js' fuzz tests were built with [libFuzzer][] in mind and have only been tested with libFuzzer. ### Building fuzz tests When running CMake to configure quick-lint-js, do the following: 1. Use Clang to compile (not GCC or MSVC). 2. At a minimum, compile with the `-fsanitize=fuzzer-no-link` flag. 3. Set the `QUICK_LINT_JS_ENABLE_LLVM_LIBFUZZER_TESTS` CMake variable to `ON`. Compiling with `-fsanitize=address,undefined` (to catch undefined behavior) and `-UNDEBUG` (to enable assertions) is also recommended. For example: $ mkdir build-fuzz $ cd build-fuzz $ CC=clang CXX=clang++ CFLAGS='-fsanitize=address,undefined,fuzzer-no-link' CXXFLAGS='-fsanitize=address,undefined,fuzzer-no-link' \ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DQUICK_LINT_JS_ENABLE_LLVM_LIBFUZZER_TESTS=ON .. $ cd - Then, build the fuzz test executables: $ ninja -C build-fuzz $ ls build-fuzz/fuzz CMakeFiles quick-lint-js-fuzz-parse cmake_install.cmake quick-lint-js-fuzz-utf-8-decode-encode quick-lint-js-fuzz-lex quick-lint-js-fuzz-utf-8-lsp quick-lint-js-fuzz-options ### Running fuzz tests Create a directory to contain the fuzz corpus files. I recommend one directory per fuzz test: $ mkdir -p fuzz-corpus/quick-lint-js-fuzz-lex/ $ mkdir -p fuzz-corpus/quick-lint-js-fuzz-options/ $ mkdir -p fuzz-corpus/quick-lint-js-fuzz-parse/ $ mkdir -p fuzz-corpus/quick-lint-js-fuzz-utf-8-decode-encode/ $ mkdir -p fuzz-corpus/quick-lint-js-fuzz-utf-8-lsp/ Run a fuzz-test executable, giving it the corpus directory as an argument: $ ./build-fuzz/fuzz/quick-lint-js-fuzz-lex fuzz-corpus/quick-lint-js-fuzz-lex/ For usage information, see [libFuzzer's documentation][libFuzzer] or run `./build-fuzz/fuzz/quick-lint-js-fuzz-lex -help=1`. [libFuzzer]: https://www.llvm.org/docs/LibFuzzer.html --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/INFRASTRUCTURE.md # quick-lint-js infrastructure This document describes the infrastructure used for managing builds, releases, and the website. ## Local hardware ### stracle stracle is a Mac mini (M1 Apple Silicon, 2020) in strager's basement. * GitHub Actions runner in a virtual machine * See `~/NOTES` on the host ## Hosted services ### c.quick-lint-js.com c.quick-lint-js.com is a VPS on strager's [Vultr][] account. * vhost: https://c.quick-lint-js.com/ * vhost: http://c.quick-lint-js.com/ * vhost: https://admin.quick-lint-js.com/ * vhost: http://admin.quick-lint-js.com/ * vhost: https://quick-lint-js.com/ * vhost: http://quick-lint-js.com/ * vhost: https://quicklintjs.com/ * vhost: http://quicklintjs.com/ * Matomo analytics * MariaDB database ### vhost: https://c.quick-lint-js.com/ Data updated manually and by GitHub Actions. * Data: /qljs-pool/var/www/c.quick-lint-js.com/ (Vultr block storage) * TLS certificates: Let's Encrypt * Cron: `/home/github-ci/prune-old-builds.py` run by `github-ci` * Ansible: [`quick-lint-js-web-2`][] ### vhost: http://c.quick-lint-js.com/ Redirects to https://c.quick-lint-js.com/ ### vhost: https://admin.quick-lint-js.com/ Serves several services for administration: * Matomo: * phpMyAdmin: * TLS certificates: Let's Encrypt ### vhost: http://admin.quick-lint-js.com/ Redirects to https://admin.quick-lint-js.com/ ### vhost: https://quick-lint-js.com/ is the main website for users. * Deploy script: [`website/tools/deploy.sh`](../website/tools/deploy.sh) * Source: [`website`](../website) * TLS certificates: Let's Encrypt * Docker: [`quick-lint-js-web`][] ### vhost: http://quick-lint-js.com/ Redirects to https://quick-lint-js.com/ ### vhost: https://quicklintjs.com/ Redirects to https://quick-lint-js.com/ * TLS certificates: Let's Encrypt ### vhost: http://quicklintjs.com/ Redirects to https://quick-lint-js.com/ ### Matomo analytics Analytics for the website is self-hosted with Matomo. * Database: MariaDB matomo_analytics@c.quick-lint-js.com * Admin URL: * Cron: `/root/update-analytics.sh` run by `root` ## Cloud services * Domains * DNS * Source code * Issue tracking * Continuous integration/building * Open VSX Registry * Visual Studio Marketplace * npm ### Domains Domains were purchased through strager's [Namecheap][] account. ### DNS DNS nameservers are hosted through strager's [DNS Made Easy][] account. ### Source code hosting GitHub hosts quick-lint-js' repositories: ### Issue tracking GitHub hosts quick-lint-js' issue tracker: ### Continuous integration/building quick-lint-js uses GitHub Actions for continuous integration (aka automated building): Note: *stracle* runs a self-hosted GitHub Actions runner ### Open VSX Registry strager owns the [quick-lint-js package](https://open-vsx.org/extension/quick-lint/quick-lint-js) on the Open VSX registry ### Visual Studio Marketplace strager owns the [quick-lint publisher account](https://marketplace.visualstudio.com/publishers/quick-lint) on the Visual Studio Marketplace. ### npm strager owns the [quick-lint-js package](https://www.npmjs.com/package/quick-lint-js) on the npm registry. [DNS Made Easy]: https://dnsmadeeasy.com/ [Namecheap]: https://www.namecheap.com/ [Vultr]: https://www.vultr.com/ [`quick-lint-js-web-2`]: ../infrastructure/quick-lint-js-web-2/README.md --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/INSTALLING.md # Installing quick-lint-js For quick-lint-js installation instructions, see the [installation instructions](https://quick-lint-js.com/install/) on the website. For instructions on building quick-lint-js, see [BUILDING instructions][build-from-source] for developers [build-from-source]: https://quick-lint-js.com/contribute/build-from-source/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/RELEASE.md # Releasing quick-lint-js To release a new version of quick-lint-js, run the `dist/release.go` tool: # Replace '1.2.3' with the desired version number. $ go run dist/release.go 1.2.3 --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/TRACING.md # Tracing in quick-lint-js quick-lint-js supports a binary log format. This document describes the format and tools used to process the format. See [ADR005 Logging and tracing](architecture/ADR015-Logging-and-tracing.md) for rationale. ## Format quick-lint-js' binary log is compatible with the [Common Trace Format][]. The format of each stream is described by a [CTF metadata file](../src/quick-lint-js/trace-metadata.cpp). A trace is a directory containing a *metadata file* and one or more *stream files*. The metadata file is a text file describing the format of the stream files. The metadata file is called `metadata` in the directory, as expected by [Babeltrace][]. A stream file is a binary file containing logged data. Each stream file is called `thread###` (where `###` is one or more decimal digits). ## Producing traces To produce a trace with the Visual Studio Code extension, set the `quick-lint-js.tracing` setting to `"verbose"`. To find the trace directory: Open the Command Palette (ctrl-shift-P) then type "Developer: Open Extension Logs Folder". Open the `quick-lint.quick-lint-js` directory. Traces are written into a directory named `trace_%TIMESTAMP%` (e.g. `trace_2022-05-17-19-41-14.zlNiwm`). ## Consuming traces There are a few tools which can consume traces produced by quick-lint-js. ### quick-lint-js-analyze-trace Build the quick-lint-js-analyze-trace CMake target, then run it with a trace file. For example: $ ninja -C build quick-lint-js-analyze-trace $ ./build/tools/quick-lint-js-analyze-trace .../thread1 @0000.000000000 init version='2.4.2' @0000.000000000 document 0x2b40027ce4c0 opened: file:///home/strager/Projects/quicklint-js/sandbox/hello.js @0000.000000000 document 0x2b40027ce4c0 changed 3:0->3:0: 'h' [snip] @0000.000000000 document 0x2b40027ce4c0 changed 3:9->3:10: '' $ ./build/tools/quick-lint-js-analyze-trace --dump-final-document-content 0x2b40027ce4c0 .../thread1 const x = 3; x = 4;sadasdsad hello hellohell ### Babeltrace The [Babeltrace][] tool can dump traces: $ babeltrace2 ~/.config/Code/logs/20220516T161030/exthost22/quick-lint.quick-lint-js/2022-05-17-19-29-57.zVvhTp [16:00:00.000000000] (+?.?????????) init: { thread_id = 164877, compression_scheme = 0 }, { quick_lint_js_version = "2.4.2" } [16:00:00.000000000] (+0.000000000) vscode_document_opened: { thread_id = 164877, compression_scheme = 0 }, { doc_id = 3221267211232, uri = { code_unit_count = 60, code_units = [ ... ] }, language_id = { code_unit_count = 15, code_units = [ ... ] }, content = { code_unit_count = 110, code_units = [ ... ] } } [16:00:00.000000000] (+0.000000000) vscode_document_closed: { thread_id = 164877, compression_scheme = 0 }, { doc_id = 0, uri = { code_unit_count = 12, code_units = [ ... ] }, language_id = { code_unit_count = 3, code_units = [ ... ] } } [16:00:00.000000000] (+0.000000000) vscode_document_opened: { thread_id = 164877, compression_scheme = 0 }, { doc_id = 3221267214816, uri = { code_unit_count = 59, code_units = [ ... ] }, language_id = { code_unit_count = 10, code_units = [ ... ] }, content = { code_unit_count = 35, code_units = [ ... ] } } ### 010 Editor [010 Editor][] is a hex editor which supports decoding file formats. [trace.bt](../tools/trace.bt) contains a plugin (*template*) for 010 Editor, allowing you to decode and inspect quick-lint-js trace files. [010 Editor]: https://www.sweetscape.com/010editor/ [Babeltrace]: https://babeltrace.org/ [Common Trace Format]: https://diamon.org/ctf/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/TRANSLATING.md # Translating quick-lint-js ## Updating messages.pot after changing quick-lint-js After editing quick-lint-js' source code, build the `quick-lint-js-i18n` CMake target. (This is built for you if you build the main `quick-lint-js` executable, any tests or benchmarks, or any plugin.) This will update po/messages.pot and also quick-lint-js/i18n/translation-table-generated.cpp, quick-lint-js/i18n/translation-table-generated.h, and quick-lint-js/i18n/translation-table-test-generated.h. Be sure to commit changes to the updated files. ## Updating .po files after changing quick-lint-js or messages.pot Update the po/\*.po files by running the `tools/update-translator-sources` script. You'll need to install the following third-party dependencies: * [GNU gettext][] ## Updating translation-data.cpp after changing .po files After editing a translation file (\*.po), update the generated C++ source files by building the `quick-lint-js-i18n` CMake target. This will change quick-lint-js/i18n/translation-table-generated.cpp and quick-lint-js/i18n/translation-table-test-generated.h. Be sure to commit changes to the updated files. ## Adding a new language To add a translation for a new language, run `tools/create-translation --locale=fr_FR` (changing the locale as appropriate). This script creates a file in the po directory for your language. See documentation for [GNU gettext msginit][] for details. Then, list the .po file in the `QLJS_TRANSLATION_FILES` list in src/CMakeLists.txt. [GNU gettext]: https://www.gnu.org/software/gettext/ [GNU gettext msginit]: https://www.gnu.org/software/gettext/manual/html_node/Creating.html#Creating --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR001-Feature-testing-with-have-h.md # ADR001: Feature testing with have.h **Status**: Accepted and active. ## Context Different operating systems support different APIs. Different compilers support different language features. Sometimes, implementations are broken and require workarounds. quick-lint-js is a portable software project. quick-lint-js compiles with different compilers and for different operating systems. Parts of quick-lint-js need to react to differences and quirks of the compilation environment. Traditionally, C++ programs use *feature test macros* to control how they use operating system and language features. Projects have different mechanisms for exposing these feature test macros to the C++ compiler. ## Decision `` defines macros with names starting with `QLJS_HAVE_`. A macro is defined with value `1` if a feature is likely present and working, and is defined with a value of `0` if a feature is likely absent or broken. The value of `QLJS_HAVE_` macros are decided by checks using the C++ preprocessor, such as `#if __has_include` and `#if defined(__unix__)`. All `QLJS_HAVE_` macros are always defined, regardless of whether the macro is used or whether the feature is present. As a corollary, uses of `QLJS_HAVE_` macros use `#if`, never `#ifdef`. If a `QLJS_HAVE_` macro is defined before `` is included, its original value is preserved; including `` has no effect on that macro. ## Consequences Testing exclusively in C++ means that the build system can be simpler. For example, on major platforms with recent compilers, all of quick-lint-js can be compiled with a few basic compilation command lines with no explicit macro definitions. If a `QLJS_HAVE_` macro's checks are incorrect in ``, a porter/packager can define the macro with its correct value in the build system without patching quick-lint-js' source code The C++ preprocessor code checks to decide the value of a `QLJS_HAVE_` macro might be error prone or downright incorrect. In practice, some `QLJS_HAVE_` macros need to be configured in the build system because the C++ preprocessor is not powerful enough. `QLJS_HAVE_CHARCONV_HEADER` is one historical example. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR002-Programming-language.md # ADR002: Programming language **Status**: Accepted and active. ## Context Software engineers choose programming languages for a variety of reasons. The choice of a programming language has major consequences. The wrong choice can destroy or severely delay a project. ## Decision quick-lint-js's main components are written in C++. quick-lint-js' editor plugins are written in a mix of C++ and the editor's native plugin language. ## Consequences C++ is familiar to strager, the original author of quick-lint-js. This makes strager productive and happy. C++ is a popular programming language in the free software, compiler, and open source communities. This makes it easier to attract talent and patches. C++ programs can have a low start-up time, which made a quick-and-dirty LSP-less Vim plugin very effective for getting a feel for quick-lint-js. C++ gives the programmer access to CPU features such as x86's SSE, making it easier to optimize. C++ can compile to WebAssembly using emscripten, making it possible to run C++ in the web browser for web demos. C++ is unpopular for JavaScript tooling compared to JavaScript. Convincing JavaScript enthusiasts to contribute to a C++ codebase might be a challenge. C++'s integration with typical JavaScript tooling such as npm is weak. Integrating a fast CLI build with npm requires distributing different pre-compiled executables for different platforms, increasing download size and adding to the complexity of the release processing. Not writing all of quick-lint-js in Vimscript makes it more difficult to install quick-lint-js in Vim. C++' template feature made it possible to mock with zero run-time overhead. This made fine-grained testing a lot easier. This was the primary reason quick-lint-js was not originally written in C. However, as of commit 40a89e9e22952d1bd1a6ac7e0132ceda28efdbf4, templates are no longer needed for mocking in tests. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR003-Vendor-sources.md # ADR003: Vendor sources **Status**: Accepted and active. ## Context The quick-lint-js project demands functionality which can be outsourced to third parties. Using external libraries and programs is common in C++, but there are many strategies for referencing and using these dependencies. ## Decision Run-time dependencies are extracted from source code release archives into the `vendor` directory. For each dependency, `vendor/README.txt` documents the name of the dependency, precisely where it was extracted to, usage licensing and copyright, where it was downloaded from, and other information. Run-time dependencies are integrated with quick-lint-js' CMake build system using `add_subdirectory` if possible. Compile-time dependencies are disallowed aside from the following: * compiler toolchain (compiler, linker, archiver, etc.) * build system (CMake, Ninja, Visual Studio, Xcode, etc.) * source control system (Git, HTTPS client, etc.) Development tool dependencies are discouraged, but are allowed for some files. See [ADR004](ADR004-Generated-sources.md) for details. ## Consequences quick-lint-js can use API-unstable software, such as simdjson, without being tied to the versions supported by popular distributions (like Homebrew or Debian). We can patch bugs found in third-party dependencies without waiting for a formal release. (`googletest-result-of.patch` is a good example of this.) In most cases, build instructions are simple for contributors. Including third-party project source code bloats the Git repository, slowing down fresh clones of the repository. The extra code inflates the line-of-code metrics on GitHub. Because code bloat can be a problem with Git repositories, lots of engineering time has been spent reducing the size of vendor projects (especially Boost). This complicates maintenance. For example, because of the work done to reduce Boost's footprint, upgrading Boost is more complicated than extracting the new source archive. Some projects have partially broken or hostile CMake build systems which sometimes need to be worked around with hacks of our own. Some people might be confused by the term `vendor`. Perhaps `third-party` would be a better name. The structure of `vendor/README.txt` makes it a bit easier to generate copyright documents for release. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR004-Generated-sources.md # ADR004: Generated sources **Status**: Accepted and active. ## Context Sometimes, source code needs to be compiled with tools not typically part of a language's toolchain. For example, Flex compiles .l files into .c files, and those .c files should be compiled with the normal C toolchain. In this document, we refer to these tools as *unorthodox tools*, their inputs as *unorthodox sources* or *unorthodox source files*, and their corresponding outputs as *unorthodox artifacts*. In a perfect world, unorthodox tools could either be avoided entirely or could integrate seamlessly with build systems. In the real world, tradeoffs must be made. ## Decision Unorthodox artifacts (in addition to unorthodox sources) are checked into the source code repository. Each unorthodox artifact must include the word 'generated' in its file name. Each unorthodox artifact must mention in a comment at the top of the file that the file is generated, which unorthodox tool generated the file, and what the unorthodox sources were. The set of unorthodox source files is kept small. Most changes a typical contributor might make do not involve those source files. Unorthodox tools are not included in the `vendor` directory (see [ADR003](docs/architecture/ADR003-Vendor-sources.md)). ## Consequences No unorthodox tools is required in order to build quick-lint-js. Unorthodox tools are only required when changing certain source files. It's clear whether a file which is checked into the repository is generated. A contributor might modify an unorthodox artifact, but there are several indications that this is a bad idea. Different versions of unorthodox tools can produce different artifacts given the same sources. This can cause thrash it Git logs if two developers trade changes to sources but use different different tool versions. The set of unorthodox sources turned out to be larger than anticipated. For example, *all* sources are potentially unorthodox sources for the translation tools, and the often-changed `diagnostic-types.h` file is definitely an unorthodox source. It's easy for unorthodox artifacts to get out of sync with their unorthodox sources. This is clearly true for translation files (.po). Generation scripts are written in various languages. Some languages are a bit hostile to certain platforms, such as POSIX shell on Windows. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR005-Incremental-lexing.md # ADR005: Incremental lexing **Status**: Accepted and active. ## Context Parsers for programming languages are generally split into two phases: lexing and parsing. There are various strategies for how lexing and parsing are interleaved, and each has its own tradeoffs. ## Decision Lexing is done one token at a time. The parser requests that the lexer feed the parser a new token, and to satisify that request, the lexer lexes the token (and only that token). ## Consequences The lexer doesn't need much state. It doesn't need to know the depth of template literals. It doesn't need to know whether a `/` should be interpreted as a division operator or the start of a regular expression literal. The lexer's interface is non-trivial. The parser needs to call different lexing functions depending on the state of the parser (`skip`; `skip_in_template`; `reparse_as_regexp`; `insert_semicolon`). Backtracing the lexer results in re-lexing. Therefore, backtracking is discouraged in the parser for performance reasons. The CPU switches between lexing and parsing frequently. This might have a negative impact on performance, especially for CPUs with smaller icaches. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR006-Location-tracking.md # ADR006: Location tracking **Status**: Accepted and active. ## Context In order to provide good diagnostics, compilers report *where* in the source code an error occurs. Editors consume this location information in order to highlight issues for the user. In addition to reporting diagnostics, incremental compilers (e.g. LSP servers) need to consume location information given by editors when the user makes changes to their source code. Different editors use different schemes for communicating locations. Some editors use byte offsets, and others use line-and-column-number. Editors which use line and column numbers use different methods for counting lines (e.g. first line is 0 or 1; lines end in CR/LF/CRLF or maybe some other sequences) and counting columns. ## Decision The lexer does not count line or column numbers. The lexer only communicates a pointer inside the input string (effectively a byte offset). Different `_Locator` classes are used to implement different rules used by different editors. Each `_Locator` class is independent and has a different interface suited for the protocol. (A CLI `_Locator` class has different needs from an LSP server `_Locator` class.) When reporting an error, it is the responsibility of an `Error_Reporter` derived class to give the input string pointer (i.e. byte offset) to the `_Locator`. ## Consequences For the CLI, if source code has no errors, location information is not needed, thus quick-lint-js avoids redundant work. The `_Locator` system came in handy when implementing the LSP server. When applying line-number-based edits from the LSP client, line numbers don't need to be recomputed in order to find which byte to edit in the input string. Different `_Locator` classes can coexist while reusing the same lexer code. The lexer doesn't need a polymorphic (e.g. template parameter) reference to any state to keep track of line numbers. Passing around location-aware tokens involves just passing two pointers (start and end). This representation is pretty compact compared to a bunch of integers. For identifiers, we need the pointers anyway (though Unicode escapes in identifiers tarnish the utopia of only needing two pointers). If multiple diagnostics need to be reported, then the `_Locator` classes need caching to avoid scanning the input multiple times. This caching is hard to get right, and has lead to several bugs (e.g. Git commits e33b0a4ed72d236ccee9615ba42978ee72a92aff and 507bbfa75802bd0ec71d91f8c6bfec94dc48116e). --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR007-Expression-stack.md # ADR007: Expression stack **Status**: Rejected. ## Context JavaScript expressions are complicated. Most compilers create ASTs to represent expressions in languages like JavaScript. quick-lint-js aims to be fast. Constructing and traversing ASTs is expensive, especially if traversing is done only once. quick-lint-js has different needs from most compilers, so it can use other techniques for parsing expressions which require less allocation and copying. ## Decision When parsing an expression, the parser maintains a stack of nodes. When the parser is certain how a node should be treated, it immediately removes that node from the stack and tells the variable analyzer about it. When parsing an expression such as `a+b`, the parser performs these steps: 1. See `a`: Push variable reference `a`; go to pending-operator state. 2. See `+`: Report top as a *use* (`visit_variable_use`); pop; go to pending-primary state. 3. See `b`: Push variable reference `b`; go to pending-operator state. 4. See end: Report top as a *use* (`visit_variable_use`). When parsing an expression such as `a=b`, the parser performs these steps: 1. See `a`: Push variable reference `a`; go to pending-operator state. 2. See `=`: Report top as an *assignment* (`visit_variable_assignment`); pop; go to pending-primary state. 3. See `b`: Push variable reference `b`; go to pending-operator state. 4. See end: Report top as a *use* (`visit_variable_use`). When parsing an expression such as `a[i] = n`, the parser performs these steps: 1. See `a`: Push variable reference `a`; go to pending-operator state. 2. See `[`: Report top as a *use* (`visit_variable_use`); pop; push open-square node; go to pending-primary state. 3. See `i`: Push variable reference `i`; go to pending-operator state. 4. See `]`: Report top as a *use* (`visit_variable_use`); pop; pop open-square node; go to pending-operator state. 5. See `=`: Pop; go to pending-primary state. 6. See `n`: Push variable reference `n`; go to pending-operator state. 7. See end: Report top as a *use* (`visit_variable_use`). ## Consequences The logic needed to implement this scheme turned out to be complicated. Nodes needed to be variable-length anyway (e.g. `[a,b,c,d].map()` vs `[a,b,c,d]=xs` both need the set of variables inside the array literal for different reasons). It was too hard to implement. An AST-based approach was extremely easy to implement in comparison. Expression parsing didn't seem to be a major bottleneck in the parser. Lexing and variable lookup are a bigger hotspots compared to an AST-based expression parser. Therefore, the performance benefits of this expression stack scheme would be overshadowed by the performance costs of other parts of quick-lint-js. Optimization effort is better spent elsewhere. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR008-Exceptions.md # ADR008: Exceptions **Status**: Accepted and active. ## Context Standard C++ supports exceptions. Exceptions (`try`, `catch`, `throw`) are often used for error signaling and handling. Other techniques exist as well, such as returning error codes and `setjmp`/`longjmp`. Production C++ compilers allow compiling with exception support disabled. This changes how code is generated, often by making it smaller and faster. ## Decision C++ exceptions are disallowed. They are disabled for production builds. Other techniques, such as returning error codes or `setjmp`/`longjmp`, are used for error signalling and handling instead of exceptions. ## Consequences If C++ exceptions were required, WebAssembly generated by Emscripten would need non-trivial JavaScript support code. Because C++ exceptions are disabled, WebAssembly generated by Emscripten is straightforward and needs little support code. Enabling and using C++ exceptions increases file size by a significant amount (e.g. 50 KiB for WebAssembly, excluding JavaScript support code) compared to disabling C++ exceptions. `setjmp`/`longjmp` is foreign to many C++ programmers and is harder to use than C++ exceptions. simdjson's On Demand API exposes parse errors in every API call. This means that error handling code needs to be written all over. simdjson's exception-based On Demand API would simplify error handling significantly. We haven't determined yet whether `setjmp`/`longjmp` can be used. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR009-Website.md # ADR009: Website **Status**: Accepted and active. ## Context quick-lint-js needs a website for marketing purposes but also as a way to distribute installation and usage documentation. Static HTML files are easy to manage for simple websites. However, quick-lint-js' website has enough complex pages that manually maintaining static HTML files becomes painful. Generated files need to be manually re-generated when the source changes. Repeated elements such as navigation are error-prone and time-consuming to write and update. ## Decision [EJS][]-based template files are checked into the source repository. Node.js-based software converts the EJS-based template files into HTML. A dynamic web server exists for developers, and a build script exists for deployment to GitHub Pages (or any other static file server). HTML generation logic is written in Node.js as much as possible, and is invoked from EJS template files. ## Consequences Contributors and users can no longer see most of the website on their local machine by just downloading a copy of the source repository. A build step is needed to convert sources into HTML. Generated HTML code is always up-to-date because generation is coupled with deployment. Code generation scripts are still necessary for man pages and other non-web output formats. [EJS]: https://ejs.co/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR010-LSP-server.md # ADR010: LSP server **Status**: Accepted and active. ## Context The [Language Server Protocol (LSP)][LSP] makes code editor plugins easier to write by standardizing several aspects of editor<->language interaction. In an LSP world, there are three major components: * editor (language-agnostic) * editor plugin (LSP client) (editor-specific; language-specific) * language server (LSP server) (editor-agnostic; language-specific) Developers of language tooling are expected to implement the language server. [LSP]: https://langserver.org/ ## Decision quick-lint-js develops its own LSP server. It is integrated into the same executable as the CLI and is accessible with the `--lsp-server` option. quick-lint-js develops its own editor plugins. Some of these editor plugins utilize the LSP server. JSON parsing is done with simdjson. JSON serializing is done manually. ## Consequences LSP has some accidental complexities. For example, locations count the number of UTF-16 code units since the beginning of a line. Counting in this way is non-trivial for the LSP server and is complicated for some LSP clients (editors) too. Non-LSP editor plugins don't necessarily have this complexity; quick-lint-js can use the editor's native location scheme without multiple layers of translation. Error handling with simdjson, particularly with its On Demand API, is tedious. This is because of [ADR008: Exceptions][ADR008] banning exception in quick-lint-js. simdjson's exception-based interface would be much easier to use. Contrary to what LSP marketing might imply, LSP still requires editor plugins to be written for the specific LSP server. Developing and maintaining editor plugins for popular editors is still necessary with LSP. [ADR008]: ./ADR008-Exceptions.md --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR011-IO-errors.md # ADR011: IO errors **Status**: Accepted and active. ## Context quick-lint-js needs to interact with various system APIs, mostly filesystem APIs. There are several possibilities for communicating these I/O errors: * C++ exceptions or setjmp/longjmp * Note: [ADR008 bans C++ exceptions](ADR008-Exceptions.md) * Variant of result and error information (e.g. std::variant; boost::outcome) * Optional result with out-of-band error information (e.g. POSIX errno; Win32 GetLastError(); [LEAF][]) ## Decision Functions which might fail due to an I/O error return `Result` where `Error` is some class whose names end with `_IO_Error`. An `_IO_Error` class stores all information relevant to the function (or functions it calls). `_IO_Error` objects can be converted to a human-readable message. ## Consequences Human-readable messages are easy to format from the member variables of `_IO_Error` classes. Error types are easy to store and compare. This matters for `Configuration_Loader` which needs to detect when an error changes (in order for the UI to report changes to the user). Storing errors with [LEAF][] is difficult (and this was the reason we switched away from LEAF). Errors need to be converted. For example, `Read_File_IO_Error` and `Canonicalize_Path_IO_Error` need to be converted to `Configuration_Load_IO_Error`. * `Result<>::propagate` became a natural mechanism to perform conversions, and this turned out to be simpler and cleaner than expected. * Error type conversion can lead to quirks such as `Configuration_Load_IO_Error::canonicalizing_path` being only sometimes used. * Error type "hierarchies" need to be constructed manually. A library like [LEAF][] would automate this composition. Some error types contain extra information such as the path which errored. This information is used in tests to make sure certain error conditions occur. However, this complicates errors slightly just for testing. [LEAF]: https://www.boost.org/doc/libs/1_76_0/libs/leaf/doc/html/index.html --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR012-Assertions.md # ADR012: Assertions **Status**: Accepted and active. ## Context Software bugs happen. [Defensive programming][] is one way to catch bugs early and to reduce damage when bugs happen. A common defensive programming technique is the *assertion*. C++ has a built-in assertions library called `` which defines a macro called `assert`. Many C++ libraries have their own assertion macros. ## Decision * `` defines custom assertion macros. `` is avoided. * Defining `NDEBUG` disables assertions, except assertions marked `ALWAYS`. * Defining `QLJS_DEBUG` enables extra assertions. * A default CMake build (where `CMAKE_BUILD_TYPE=None`) enables assertions. * An optimized CMake build (where `CMAKE_BUILD_TYPE=Release`) disables assertions (except assertions marked `ALWAYS`). ## Consequences Assertions can slow down execution. This used to negatively affect quick-lint-js' Debian package (where assertions are enabled), hurting quick-lint-js in benchmarks. A custom macro reduces usage of `[[maybe_unused]]`. A custom macro traps debuggers at the offending line of code, not some `__assert_imp` or `_abort` function a few call frames down. Assertion failures on Linux and macOS lead to SIGILL ("illegal instruction"). This confuses people. [defensive programming]: https://en.wikipedia.org/wiki/Defensive_programming --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR013-Dependencies.md # ADR013: Dependencies **Status**: Accepted and active. ## Context Rarely does a project develop all of its own tools from scratch. Projects depend on compilers, interpreters, libraries, and operating systems written by others. quick-lint-js might want to rely on other tools for several needs. ## Decision quick-lint-js has three categories of dependencies: in-build, out-build, and dev. In-build dependencies are necessary to build and run quick-lint-js, but are provided in quick-lint-js' source distribution. These dependencies are written in C or C++ (see [ADR002](ADR002-Programming-language.md)) and exist in the `vendor/` directory of the repository (see [ADR003](ADR003-Vendor-sources.md)). Out-build dependencies are necessary to build and run quick-lint-js, but are *not* provided in quick-lint-js' source distribution. The following out-build dependencies are allowed: * CMake and a supported build system * C++ compiler and standard library * Python 3 * Tooling to download quick-lint-js' code, such as Git or curl+tar+gunzip Dev dependencies are *not* necessary to build and run quick-lint-js, and are *not* provided in quick-lint-js' source distribution. The following is an incomplete list of dev dependencies: * Asciidoctor * Bash * Go (programming language) * Node.js and npm * Packages installed through npm * clang-format * cloc ## Consequences Keeping the list of out-build dependencies small makes it easier for new developers to start developing quick-lint-js. Keeping the list of out-build dependencies small and using only industry-standard tools makes it easier to package quick-lint-js in software distributions. Limiting out-build dependencies means generated sources need to be checked into the source repository. This has negative consequences, generated sources getting out of date with their source code. See [ADR004](ADR004-Generated-sources.md) for details. Mixing programming languages in dev dependencies reduces code reuse. This has only been a problem for a few things so far (e.g. Python check-esprima vs Go check-test262 Allowing best-tool-for-the-job in dev dependencies is sometimes a good thing. For example, check-test262.go was originally written in Python, but it was too slow. A prototype in Node.js was also too slow. The Go version was nice and fast. Web developers are likely familiar with Node.js and npm, so the website backend being written in Node.js makes it easier to for new contributors to the website to get up and running. We have a few "soft" out-build dependencies. `test/test-lex-unicode.cpp` requires the third-party icu4c library, but if icu4c is missing, that test file is not compiled. This is kinda gross, and means we don't get full testing everywhere. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR014-Plugins.md # ADR014: Plugins **Status**: Accepted and active. ## Context Static analysis tools an have every-growing list of patterns to check. Some patterns are team-specific and don't make sense to include in the main static analyzer code base. A common solution for third-party patterns is a plugin architecture. quick-lint-js is written in C++. Plugins in C++ typically impose a few constraints: * verisioning: stable ABI or RPC * security: plugins can't be sandboxed (unless NaCl or WebAssembly is used), and loading plugins from a project's directory is risky * compilation: plugins may need to be compiled for many architectures, similar to quick-lint-js itself. Areas of quick-lint-js a plugin might want to integrate with: * linting * error reporting * auto-fixes * configuration * parsing and lexing ## Decision quick-lint-js will not support plugins. ## Consequences Users of quick-lint-js cannot write custom, fast rules, even if they would be relatively easy to implement. quick-lint-js isn't locked into a particular design for parsing, rules, or reporting errors. This has negatively affected [Babel](https://rome.tools/blog/2020/08/08/introducing-rome#history) before, but hasn't affected quick-lint-js yet. The quick-lint-js team didn't need to spend the engineering time designing a plugin architecture and getting feedback from users. Plugins can't slow down quick-lint-js and give it a bad impression. (Plugins can and do slow down tools like ESLint and Babel.) --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR015-Logging-and-tracing.md # ADR015: Logging and tracing **Status**: Accepted and active. ## Context Server programs need to log data for a variety of reasons, including the following: * errors * general activity * performance Logged data needs to be consumed, either by humans directly or by analysis tools. quick-lint-js can run as a server or something server-like. Its LSP server is a long-running server, and its Visual Studio Code extension is also long-running. ## Decision quick-lint-js has two mechanisms: logging and tracing. ### Logging Debugging messages are strings which are appended to a text file. If the C++ macro `QLJS_DEBUG_LOGGING_FILE` is defined, messages are logged to the file at that path. To write messages, call the `QLJS_DEBUG_LOG` macro. ### Tracing quick-lint-js can write a binary log. The format is compatible with the [Common Trace Format][] and is described by a [CTF metadata file](../../src/quick-lint-js/trace-metadata.cpp). See the [documentation on our tracing format](../TRACING.md). ## Consequences ### Logging Logging to a file (rather than stdout/stderr) is useful when using vscode-test. vscode-test often swallows data written to stdout and stderr. Controlling logging with a macro is gross. quick-lint-js needs to be rebuilt in order to enable or disable logging, and logging can accidentally be enabled (see commit 149f3a64ab513ef594598bb17c751a4947aafc6c). Logging can't reasonably be enabled for end users. Logging text is slow and is thus avoided, even when it might be useful. Line-oriented logs don't allow for binary data, such as bytes that might come from an input file. Log files aren't rotated, causing them to grow indefinitely. Logging is straightforward and familiar to C and C++ programmers as it requires only `printf`-style format strings. The logging implementation is simple (as it relies on the C++ standard library to do string formatting and file I/O). ### Tracing The binary log format has been useful for tracking correctness bugs ([example](https://github.com/quick-lint/quick-lint-js/issues/683)). The logging code needs to be refactored. The names are confusing, and it's more code than I think should be necessary to log things. [Common Trace Format]: https://diamon.org/ctf/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR016-Collections.md # ADR016: Collections **Status**: Accepted and active. ## Context Programs need to deal with variable-sized data, and quick-lint-js is no exception. Strings, arrays, and dictionaries are needed for various tasks. There are many implementations for such collections with different tradeoffs. ## Decision quick-lint-js uses a mix of standard and custom collections. Code for custom collections lives in [`src/quick-lint-js/container/`](../../src/quick-lint-js/container/). For fixed-sized lists, quick-lint-js uses: * C-style arrays * `std::array` For variable-sized lists, quick-lint-js uses: * `quick_lint_js::Bump_Vector` in performance-critical code * `quick_lint_js::Linked_Vector` where pointer stability is required * `quick_lint_js::Byte_Buffer` for byte arrays destined for I/O syscalls * `quick_lint_js::Padded_String` for strings which need to be parsed * C strings, `std::string`, and `quick_lint_js::String8` (`std::basic_string`) for strings * `std::vector` otherwise * Banned: `std::deque` * Banned: `std::list` * Banned: `std::slist` For associative dictionaries, quick-lint-js uses: * `quick_lint_js::Hash_Map` * `quick_lint_js::Hash_Set` * Banned: `std::unordered_map` (except when implementing `quick_lint_js::Hash_Map`) * Banned: `std::unordered_set` (except when implementing `quick_lint_js::Hash_Set`) * Banned: `std::map` * Banned: `std::set` For functions, quick-lint-js uses: * Polymorphic base classes * `quick_lint_js::Heap_Function` * Banned: `std::function` For variants, quick-lint-js uses: * `std::optional` * `quick_lint_js::Result` * `quick_lint_js::Variant` * Banned: `std::variant` ## Consequences Implementing custom collections lets us add convenience functions, such as a backport for `contains` on `Hash_Set` (`std::unordered_set`). Custom collections easily reduce compile times compared to standard library options. This was the motivation for custom `std::deque`, `std::function`, and `std::variant`. Custom collections can be instrumented more easily, making performance tuning easier. See the [vector profiler](../profiling.md#vector-profiler) for an example. Custom collections means lots of code, opening us up to more bugs. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR017-Lexer-tables.md # ADR017: Lexer tables **Status**: Rejected. ## Context There are a few approches to writing lexers for programming language source code: * Manual `if`/`switch` statements * Table-based lexer generators such as [flex][] * Hybrid table+`if`/`switch` lexer quick-lint-js needs to be fast, thus it should be written using the fastest lexing approach. ## Decision Write a hybrid table+`if`/`switch` lexer by hand: * Symbols such as `!=` and `&&` are recognized using state machine tables. * Identifiers, numbers, strings, etc. are detected by looking at the first character. Parsing for these things is done by hand (e.g. using SIMD), not using state machine tables. ## Consequences Parsing performance was at least 1.2% slower compared to a manual `switch` lexer on several compilers on several architectures. The lexer state machine tables were much harder to read and modify compared to plain C++ `switch` statements. [flex]: https://github.com/westes/flex --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ADR018-Naming-style.md # ADR018: Naming style **Status**: Accepted and active. ## Context Symbols in programs need to be named. There are several common conventions for naming symbols, even in C++. Consistent naming improves readability and reduces developer infighting. ## Decision quick-lint-js uses the following styles for C++ code based on the C++ standard library's naming conventions: * types * classes: `Upper_Snake_Case` * enums: `Upper_Snake_Case` * type aliases: `Upper_Snake_Case` * type template parameters: `Upper_Snake_Case` * values * local variables: `lower_snake_case` * global variables: `lower_snake_case` * member variables * public: `lower_snake_case` * private: `lower_snake_case_` (trailing underscore) * enum members: `lower_snake_case` * parameter variables: `lower_snake_case` * variable template parameters: `lower_snake_case` * functions * free functions: `lower_snake_case` * class methods: `lower_snake_case` * misc * macros: `SHOUTING_SNAKE_CASE` * namespaces: `lower_snake_case` * file names: `lower-kebab-case` * concepts: `lower_snake_case` ## Consequences Previously, because types and values have the same naming convention, we are sometimes forced to either qualify a variable's type or choose an inferior name. For example: ```c++ quick_lint_js::output_format output_format = quick_lint_js::output_format::default_format; ``` This issue has been fixed in an update to this ADR. The code can now be more succinct: ```c++ Output_Format output_format = Output_Format::default_format; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/architecture/ARD019-IO-manager.md # ADR019: I/O manager **Status**: Accepted and active. ## Context Applications, and especially servers, need to perform I/O. They read and write files, use IPC channels to talk to other programs, and listen to filesystem changes. For example, quick-lint-js's LSP server needs to use I/O to talk to the LSP client. There are several ways to do I/O, and the details very depending on the operating system. The following are few common arrangements: * Synchronous I/O; no overlapping * Synchronous I/O overlapped using threads * Asynchronous I/O with one or more event pump threads Sometimes, these are mixed. Most of the program might use asynchronous I/O with event pumps, but the beginning of the program might read configuration files using synchronous I/O. ## Decision For LSP client-to-server and server-to-client IPC: * macOS: non-blocking pipes; kqueue event loop (`Event_Loop_Kqueue`) * Linux: non-blocking pipes; poll() event loop (`Event_Loop_Poll`) * Windows: blocking pipes with a thread for ReadFile (`Event_Loop_Windows::Registered_Pipe_Read`) and another thread for WriteFile (`Background_Thread_Pipe_Writer`) For filesystem notifications: * macOS: kqueue event loop (`Event_Loop_Kqueue`) * Linux: inotify with a poll() event loop (`Event_Loop_Poll`) * Windows: oplocks with an I/O completion port event loop (`Event_Loop_Windows`) An `Event_Loop` class centralizes the aforementioned IPC and filesystem notifications and abstracts over some platform differences. The event loop can be stopped arbitrarily. Events are registered by attaching callbacks, thus different users can listen for different events. For file I/O, use synchronous file I/O with no overlapping. ## Consequences The `Event_Loop` abstraction made it relatively easy to use `Change_Detecting_Filesystem` implementations in different environments: the LSP server (where we have full control) and the Visual Studio Code extension (where we need to avoid stepping on the Node.js event loop). Supporting different methods of I/O for different operating systems is complex. The current solution is leaning toward bankruptcy; using the `Event_Loop` abstraction requires a lot of platform-specific code (via `#if`), making the code hard to follow. Some of the caller complexity is necessary, but there is much to be improved in this area. In particular, `Event_Loop`'s interaction with `Pipe_Writer` is a portability problem. `Event_Loop` does not handle all IPC. `Pipe_Writer` handles the write part on Windows, and it is littered with `#if` too. Synchronous file I/O with no overlapping is problematic when quick-lint-js is embedded. For example, in the Visual Studio Code extension, synchronous file I/O occurs on the Node.js main thread, preventing other extensions from executing while the file I/O occurs. This is problematic for users who use network drives, for example. As another example, synchronous file I/O cannot be modelled in a web browser, thus quick-lint-js cannot run in Codespaces. (Codespaces support would [give quick-lint-js a competitive advantage](https://github.com/quick-lint/quick-lint-js/issues/417) over ESLint.) --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0001.md # E0001: variable assigned before its declaration Variables declared with `let` can only be reassigned by code below the declaration. The assignment will crash with a `ReferenceError` if you assign to the variable. ```javascript function getNumberOfChocolates() { return 3; } let shouldEatChocolates = true; if (shouldEatChocolates) { chocolates = 0; } let chocolates = getNumberOfChocolates(); ``` To fix this error, move the declaration above the assignment: ```javascript function getNumberOfChocolates() { return 3; } let shouldEatChocolates = true; let chocolates = getNumberOfChocolates(); if (shouldEatChocolates) { chocolates = 0; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0002.md # E0002: assignment to const global variable `Infinity`, `NaN`, and `undefined` are global variables which cannot be changed. Assignments to these variables are silently ignored. ```javascript NaN = 0; undefined = null; ``` To fix this error, pick a different variable to assign to. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0003.md # E0003: cannot assign to const variable You cannot reassign variables declared with `const`. The assignment will crash with a `ReferenceError` if you run the code. In TypeScript, you cannot assign to `enum`s. ```javascript const pi = 3.14; pi = 6; const friends = ["Alice"]; friends = ["Bob"]; ``` To fix this error, assign to a different variable, declare a new variable with a different name, or change `const` to `let`: ```javascript let pi = 3.14; pi = 6; const friends = ["Alice"]; const acquaintances = ["Bob"]; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0004.md # E0004: assignment to const variable before its declaration You cannot reassign variables declared with `const`, and you cannot reference a variable declared with `const` above its declaration. The assignment will crash with a `ReferenceError` if you run the code. ```javascript let timeElapsed = 31; let pie = "cooking"; if (timeElapsed > 30) { pi = "cooked"; } const pi = 3.14; ``` To fix this error, assign to a different variable or declare a new variable with a different name: ```javascript let timeElapsed = 31; let pie = "cooking"; if (timeElapsed > 30) { pie = "cooked"; } const pi = 3.14; ``` See also: E0001, E0003 Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0005.md # E0005: BigInt literal contains decimal point `BigInt` literals are number literals with an `n` suffix. These literals must represent integers and cannot contain a decimal point (`.`). ```javascript let gallons = 3.50n; let pennies = 100.00n; ``` To fix this error, make the number literal a `Number` literal by removing the `n` suffix, or remove the fractional portion of the number: ```javascript let gallons = 3.50; let pennies = 100n; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0006.md # E0006: BigInt literal contains exponent `BigInt` literals are number literals with an `n` suffix. These literals must represent integers and cannot contain exponents (`e`). ```javascript let atomDiameter = 1e-10n; let score = 1e2n; ``` To fix this error, make the number literal a `Number` literal by removing the `n` suffix, or expand the exponent of the number: ```javascript let atomDiameter = 1e-10; let score = 100n; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0007.md # E0007: classes cannot be named 'let' Classes declared with `class` cannot be named `let`. ```javascript class let { bark() { console.log("woof"); } } ``` To fix this error, name the class something other than `let`, or declare the class with `var`: ```javascript class Dog { bark() { console.log("woof"); } } var let = class { bark() { console.log("woof"); } }; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0008.md # E0008: let statement cannot declare variables named 'let' Variables declared with `let` cannot be named `let`. ```javascript function getLotNumber() { return 42; } let let = getLotNumber(); console.log(let); ``` To fix this error, name the variable something other than `let`, or declare the variable with `var`: ```javascript function getLotNumber() { return 42; } let lot = getLotNumber(); console.log(lot); var let = getLotNumber(); console.log(let); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0009.md # E0009: cannot export variable named 'let' An exported function cannot be named `let`: ```javascript export function let() { console.log("access permitted"); } ``` To fix this error, name the function something other than `let`, or declare the function separately with a different name and use `export`-`as`: ```javascript export function allow() { console.log("access permitted"); } function allowAccess() { console.log("access permitted"); } export { allowAccess as let }; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0010.md # E0010: cannot import 'let' An imported function or variable cannot be named `let`: ```javascript import { let } from "./security.mjs"; ``` To fix this error, name the function or variable something other than `let`, or rename the function or variable using `import`-`as`: ```javascript import { allow } from "./security.mjs"; import { let as permit } from "./security.mjs"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0011.md # E0011: character is not allowed in identifiers ```config-for-examples { "globals": { } } ``` JavaScript allows certain non-ASCII characters in identifiers. Some characters, including most emoji, are not allowed: ```javascript-ignoring-extra-errors function 💩AndDie() { throw new Error("Not yet implemented"); } console.log(6 × 9); let sounds = { 🐶: "woof", 🐮: "moo", 🐱: "meow", }; ``` To fix this error, rename your class, function, or variable: ```javascript function die() { throw new Error("Not yet implemented"); } ``` Alternatively, replace the symbols with ASCII: ```javascript console.log(6 * 9); ``` Alternatively, write the object key or method name as a string literal: ```javascript let sounds = { "🐶": "woof", "🐮": "moo", "🐱": "meow", }; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0012.md # E0012: escaped character is not allowed in identifiers A function or variable name includes a Unicode escape sequence, and the escape sequence refers to a character which isn't allowed in a function or variable name: ```javascript let guitar\u2604 = "\uD83C\uDFB8"; let handc\uffed = true; ``` To fix this error, use the code point of a Unicode character which is allowed, or remove the extraneous backslash from the name: ```javascript let guitar\u3604 = "\uD83C\uDFB8"; let handcuffed = true; ``` The initial character in a function or variable name can be any of the following: * *ID_Start* * `$` * `_` Characters after the initial character in a function or variable name can be any of the following: * *ID_Continue* * `$` * ZWJ (U+200D) * ZWNJ (U+200C) Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0013.md # E0013: code point out of range This error has been renamed to E0207. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0014.md # E0014: expected expression before newline `throw` statements cannot have a newline between the `throw` keyword and the thrown expression: ```javascript throw new Error( "something terrible happened!" ); ``` To fix this error, add parentheses: ```javascript throw ( new Error( "something terrible happened!" ) ); ``` Alternatively, start the expression on the same line as the `throw` keyword: ```javascript throw new Error( "something terrible happened!" ); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0015.md # E0015: expected expression before semicolon `throw` statements require an expression following the `throw` keyword. It is an error to rethrow an exception by writing just `throw;`: ```javascript try { goNuts(); } catch (e) { console.error(`couldn't handle deez nuts: ${e}`); throw; } function goNuts() {} ``` To rethrow an exception, name the exception variable after `throw`: ```javascript try { goNuts(); } catch (e) { console.error(`couldn't handle deez nuts: ${e}`); throw e; } function goNuts() {} ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0016.md # E0016: expected hexadecimal digits in Unicode escape sequence In variable names and strings, a Unicode escape sequence must contain only hexadecimal digits (any of `0123456789abcdefABCDEF`). It is an error if other characters appear within a Unicode escape sequence: ```javascript console.log("List of Pok\ue9mon by weight:"); console.log("{Nidoran\u{2642male}"); ``` For an escape sequence without `{` and `}`, add `{` and `}`: ```javascript console.log("List of Pok\u{e9}mon by weight:"); ``` Alternatively, for an escape sequence without `{` and `}`, include `0` digits such that the escape sequence contains exactly four hexadecimal digits: ```javascript console.log("List of Pok\u00e9mon by weight:"); ``` For an escape sequence with `{` and `}`, ensure the `}` appears after the hexadecimal digits: ```javascript console.log("{Nidoran\u{2642}male}"); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0017.md # E0017: if statement needs parentheses around condition In JavaScript, `if` statements require parentheses around the condition. It is an error to omit the parentheses: ```javascript if 2 + 2 == 4 { console.log("Math works!"); } ``` To fix this error, add `(` and `)`: ```javascript if (2 + 2 == 4) { console.log("Math works!"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0018.md # E0018: if statement is missing '(' or ')' around condition An `if` statement is missing either `(` before the condition or `)` after the condition: ```javascript if (2 + 2 == 4 { console.log("Math works!"); } if 4 == 2 + 2) { console.log("Jedi math works!"); } ``` To fix this error, add the missing `(` or `)`: ```javascript if (2 + 2 == 4) { console.log("Math works!"); } if (4 == 2 + 2) { console.log("Jedi math works!"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0019.md # E0019: escaping '-' is not allowed in tag names; write '-' instead JSX tag names and attributes can contain Unicode escape sequences starting with `\u`. It is a syntax error for a Unicode escape sequence to resolve to the `-` character (U+002D): ```javascript-jsx function Font() { return ; } ``` To fix this error, write `-` instead of `\u{2d}` or `\u002d`: ```javascript-jsx function Font() { return ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0020.md # E0020: invalid expression left of assignment ```config-for-examples { "globals": { "steps": true, "doStep": true, "stopNumber": true } } ``` In JavaScript, you can assign to variables or properties. It is a syntax error to assign to something different, such as the result of a function call or the result of math: ```javascript function saveAccount(account, {name, pass}) { account.checkPassword(pass); account.getName() = name; account.getPassword() = pass; account.save(); } for (let step of steps) { if (step.index+1 = stopNumber) { break; } doStep(step); } ``` To fix this error, assign to a variable or property instead, or call a method to do the assignment: ```javascript function saveAccount(account, {name, pass}) { account.checkPassword(pass); account.name = name; account.changePassword(pass); account.save(); } ``` Alternatively, write `==` or `===` instead of `=`, changing the assignment into a comparison: ```javascript for (let step of steps) { if (step.index+1 === stopNumber) { break; } doStep(step); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0021.md # E0021: invalid lone literal in object literal An object literal entry must either be a `key: value` pair, a method, or variable short-hand. It is an error to use the short-hand syntax with anything except a variable name: ```javascript // A tasty enum const FRUITS = { "BANANA", "ORANGE", "STRAWBERRY", "KIWI", }; // Pre-computed for speed let smallPrimes = {2, 3, 5, 7, 11, 13, 17, 19}; ``` To fix this error, either use the `key: value` pair syntax, or use `[` `]` to create an array literal instead of an object literal: ```javascript // A tasty enum const FRUITS = { BANANA: "BANANA", ORANGE: "ORANGE", STRAWBERRY: "STRAWBERRY", KIWI: "KIWI", }; // Pre-computed for speed let smallPrimes = [2, 3, 5, 7, 11, 13, 17, 19]; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0022.md # E0022: invalid UTF-8 sequence JavaScript files are normally encoded using UTF-8. It is an error for a UTF-8 JavaScript file to contain bytes which are not valid UTF-8. quick-lint-js only supports UTF-8 JavaScript files. UTF-16, ISO-8859-1, and other encodings are not supported by quick-lint-js. Save your file as UTF-8 to check it with quick-lint-js. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0023.md # E0023: keywords cannot contain escape sequences Outside a string or template literal, Unicode escape sequences (like `\u{65}`) can be used in identifiers. However, Unicode escape sequences are not allowed if they would make an identifier look like a keyword when unescaped: ```javascript let \u{69}\u{66} = "if"; let which = \u{66}inally; ``` To fix this error, either pick a different variable name, or make a string: ```javascript let _\u{69}\u{66} = "if"; let which = "\u{66}inally"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0024.md # E0024: const/let/var with no bindings `const`, `let`, or `var` statements need to declare at least one variable. It is an error to declare nothing: ```javascript var const friends = ["strager"]; for (let of friends) { } ``` To fix this error, add a variable name: ```javascript var bestFriend; const friends = ["strager"]; for (let friend of friends) { bestFriend = friend; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0025.md # E0025: missing comma between object literal entries Object literal entries, including methods, are separated by commas. It is an error to write two entries without a comma in between: ```javascript const snuffles = { age: 7 meow() { console.log("😾") } eat() { console.log("😸") } } ``` To fix this error, include commas: ```javascript const snuffles = { age: 7, meow() { console.log("😾") }, eat() { console.log("😸") } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0026.md # E0026: missing operand for operator Binary operators (such as `*` and `>>`) require an expression (e.g. a variable or number) on both sides of the operator. Unary operators require an expression before or after the operator (depending on the operator). Ternary operators require three expressions. With some exceptions, it is an error to exclude an expression: ```javascript let ripe = true; let tasty = true; if (ripe && ) { console.log("delicious!")+; } ``` To fix this error, add an expression, or remove the extraneous operator: ```javascript let ripe = true; let tasty = true; if (ripe && tasty) { console.log("delicious!"); } ``` Note that sometimes, it *appears* that expressions can be omitted, but some operators are binary *and* unary, and some operators look like other operators conjoined. In these cases, the code might be completely valid, so quick-lint-js won't report any error: ```javascript 3**5 // different than: 3 * * 5 3<<5 // different than: 3 < < 5 7 + - 8 // same as: 7 + (-8) ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0027.md # E0027: missing semicolon after statement ```config-for-examples { "globals": { "fadeIn": true } } ``` If multiple statements are on the same line, they must be separated with a semicolon (`;`): ```javascript console.log("hello") console.log("world") $("#message").text("Logged in")fadeIn() function stop() { /*...*/ } let shouldStop = false if (shouldStop) stop() return ``` To fix this error, add a semicolon, break the line, or use a dot (`.`) to call a method: ```javascript console.log("hello") console.log("world") $("#message").text("Logged in").fadeIn() function stop() { /*...*/ } let shouldStop = false if (shouldStop) { stop(); return } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0028.md # E0028: number literal contains consecutive underscores Number literals can contain underscores (`_`) to separate digits for legibility. At most one `_` can be used between a pair of digits: ```javascript let PIN_LED = 0b0__1; const tau = 3.14159____26536 * 2; ``` To fix this error, remove extraneous underscores: ```javascript let PIN_LED = 0b0_1; const tau = 3.14159_26536 * 2; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0029.md # E0029: number literal contains trailing underscores Number literals can contain underscores (`_`) to separate digits for legibility. Underscores can only appear between digits, not after all digits: ```javascript let PIN_UART = 0b00_01; let PIN_LED = 0b01_; const tau = 3.1415926536__ * 2; ``` To fix this error, remove the trailing underscores, or write more digits: ```javascript let PIN_UART = 0b00_01; let PIN_LED = 0b01_01; const tau = 3.1415926536 * 2; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0030.md # E0030: octal literal may not have exponent Decimal number literals can contain exponents. Octal number literals, which start with an extra `0` digit, cannot contain exponents: ```javascript const googol = 01e+100; ``` To fix this error, make the number literal a decimal number literal by removing the extra leading `0`: ```javascript const googol = 1e+100; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0031.md # E0031: octal literal may not have decimal Decimal number literals can contain a decimal (fraction). Octal number literals, which start with an extra `0` digit, cannot contain a decimal: ```javascript const PI = 03.14; ``` To fix this error, make the number literal a decimal number literal by removing the extra leading `0`: ```javascript const PI = 3.14; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0032.md # E0032: legacy octal literal may not be BigInt Decimal number literals can be `BigInt` with an `n` suffix. Legacy octal number literals, which start with an extra `0` digit, cannot be suffixed with `n`: ```javascript const ID = 012127638745381751821n; const perms = 07750775077507750775n; ``` To fix this error, make the number literal a decimal number literal by removing the extra leading `0`, or use the `0o` to make the a modern octal literal: ```javascript const ID = 1234567890123456789n; const perms = 0o0775_0775_0775_0775_0775n; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0033.md # E0033: redeclaration of global variable ```config-for-examples { "globals": { "windowlib": true, "$": { "shadowable": false }, "window": { "shadowable": false } } } ``` Global variables listed in `quick-lint-js.config` with `"shadowable": false` cannot be re-declared in the global scope by a JavaScript module or script: ```javascript let window = new windowlib.Window(); let $ = (sel) => document.querySelector(sel); $('#banana')[0].peel(); ``` To fix this error, choose a different variable name, or put the variable (and code which uses the variable) into a function: ```javascript let qsa = (sel) => document.querySelector(sel); qsa('#banana')[0].peel(); function createUI() { let myWindow = new windowlib.Window(); } createUI(); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0034.md # E0034: redeclaration of variable ```config-for-examples { "globals": { "loadFriends": true } } ``` In a given function or `{}` block, a variable can only be declared multiple times if it is declared with `var` or `function`. Other types of variables can be declared only once: ```javascript let x, y, y, w; const friends = loadFriends(); const friends = friends .filter(friend => friend.name !== "strager"); class Orange { name = "orange" } class Orange { name = "banana" } function jump(player, height) { let height = height || player.height/2; } ``` To fix this error, assign to the existing variable, choose a different variable name, or delete the extra variable: ```javascript let x, y, z, w; let friends = loadFriends(); friends = friends .filter(friend => friend.name !== "strager"); class Orange { name = "orange" } class Banana { name = "banana" } function jump(player, height) { height = height || player.height/2; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0035.md # E0035: RegExp literal flags cannot contain Unicode escapes ```config-for-examples { "globals": { "headerName": true } } ``` Regular expression literals can contain flags. These flags must not be escaped using a Unicode escape sequence: ```javascript const isContentLength = /content-length/\u{69}.test(headerName); ``` To fix this error, stop being clever; write the flag letter directly: ```javascript const isContentLength = /content-length/i.test(headerName); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0036.md # E0036: stray comma in let statement ```config-for-examples { "globals": { "findCenterPoint": true } } ``` Variables declared by `const`, `let`, and `var` must be separated by a comma (`,`). It is a syntax error to have multiple commas separating variables: ```javascript let p = findCenterPoint(); let x = p.x,; let y = p.y - 1; ``` To fix this error, remove the extra comma: ```javascript let p = findCenterPoint(); let x = p.x; let y = p.y - 1; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0037.md # E0037: unclosed block comment ```config-for-examples { "globals": { "heightInCM": true } } ``` Block comments start with `/*` and end with `*/`. It is a syntax error for a block comment to start but not end: ```javascript-with-errors /* this code is really complicated. some might say too complicated. function yes() { return true; } ``` ```javascript-with-errors let heightInFeet = heightInCM /* 100; ``` To fix this error, close the comment with `*/`. ```javascript /* this code is really complicated. some might say too complicated. */ function yes() { return true; } ``` Alternatively, write an expression between `/` and `*`: ```javascript let heightInFeet = heightInCM / 3.28 * 100; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0038.md # E0038: unclosed identifier escape sequence Identifiers can contain Unicode escape sequences starting with `\u`. It is a syntax error to write `\u{` followed by hexadecimal digits without a closing `}`: ```javascript let guitar\u{3604 = "\u{D83C}\u{"; ``` To fix this error, write `}` to close the escape sequence. ```javascript let guitar\u{3604} = "\u{D83C}\u{DFB8}"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0039.md # E0039: unclosed regexp literal Regular expression literals start with `/` and end with `/`. The `/` symbol is also used for the division operator. It is a syntax error to omit the trailing `/` from a regular expression literal: ```javascript // The final / is escaped by \. let LINE_CONTINUATION_RE = / +\/m; function feetToCentimeters(feet) { // The / is interpreted as the start of a // regular expression, not the division // operator. return / 3.28 * 100; } ``` To fix this error, close the regular expression literal: ```javascript let LINE_CONTINUATION_RE = / +\\/m; ``` Alternatively, include an expression before `/` to treat the `/` as a division operator: ```javascript function feetToCentimeters(feet) { return feet / 3.28 * 100; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0040.md # E0040: unclosed string literal String literals start with `"` or `'` and end with `"` or `'`, respectively. It is a syntax error to omit the trailing `"` or `'` from a string literal. A missing terminator can happen for a number of reasons: ```javascript // The final " is escaped by \. let temp = "c:\temp\"; // String literals cannot span multiple lines. // Poem by Ian Johnson. let poem = "My code fails. I do not know why. My code works. I do not know why."; let unfinishedThought = "The solution is ``` To fix this error, ensure a backslash (`\`) is not escaping the terminator, use a template literal for multi-line strings, or just include a terminator: ```javascript let temp = "c:\\temp\\"; // Poem by Ian Johnson. let poem = `My code fails. I do not know why. My code works. I do not know why.`; let unfinishedThought = "The solution is"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0041.md # E0041: unclosed template Template literals start with and end with \`. It is a syntax error to omit the trailing \`. ```javascript-with-errors // The final ` is escaped by \. let temp = `c:\temp\`; ``` ```javascript-with-errors let unfinishedThought = `The solution to all of our problems is ``` To fix this error, ensure a backslash (`\`) is not escaping the terminating \`, or include a terminating \`: ```javascript let temp = `c:\\temp\\`; let unfinishedThought = `The solution to all of our problems is`; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0042.md # E0042: unexpected '@' This diagnostic has been removed in quick-lint-js version 2.17.0. In JavaScript, `@` is only allowed in string and template literals. It is a syntax error to write `@` anywhere else: ```javascript @ // oops // JavaScript does not support C# verbatim strings: let notepad = @"C:\Windows\System32\notepad.exe"; ``` To fix this error, remove the `@`: ```javascript let notepad = "C:\\Windows\\System32\\notepad.exe"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0043.md # E0043: unexpected '\\' in identifier ```config-for-examples { "globals": { "ChirpSound": true } } ``` Identifiers (variable names, etc.) can contain Unicode escape sequences (`\u{69}` for example). It is an error for an identifier to have a backslash which is not part of a Unicode escape sequence: ```javascript function identity\(x) { return x; } let bird\U3600 = new ChirpSound(); ``` To fix this error, remove the backslash, or complete the Unicode escape sequence: ```javascript function identity(x) { return x; } let bird\u3600 = new ChirpSound(); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0044.md # E0044: unexpected characters in number literal ```config-for-examples { "globals": { "pi": true } } ``` Letters are allowed in number literals in certain situations, such as in `123n`, `1e6`, and `0xff`. It is an error to include other letters or letters in the wrong spot: ```javascript let big = 9007199254740991N; let pi = 3.14l; let tau = 2pi; ``` To fix this error, use the correct letter or remove the extraneous letter: ```javascript let big = 9007199254740991n; let pi = 3.14; ``` Alternatively, use the `*` operator to multiply a variable by a number: ```javascript let tau = 2*pi; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0045.md # E0045: unexpected control character JavaScript treats some Unicode control characters, such as newlines, tabs, and form feeds, as whitespace. Most other control characters are now allowed outside string literals and template literals: ```javascript   ``` To fix this error, delete the extra control characters, or put them inside a comment: ```javascript /*   */ ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0046.md # E0046: unexpected characters in binary literal Binary number literals start with `0b` and can only contain `0` or `1` digits (and optionally an `n` to signify a `BigInt`). It is an error to include other digits in binary number literals: ```javascript let minInt16 = 0b1000000000000000N; let mouse = [0xf09f, 0b196]; ``` To fix this error, fix or remove the extra digits or letters: ```javascript let minInt16 = 0b1000000000000000n; ``` Alternatively, convert the binary number literal into a decimal, hexadecimal, or octal number literal: ```javascript let mouse = [0xf09f, 0xb196]; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0047.md # E0047: unexpected characters in octal literal Octal number literals start with `0` or `0o` and can only contain digits `0` through `7` (and optionally an `n` to signify a `BigInt`). It is an error to include other digits in octal number literals: ```javascript let permissions = 0o755N; let bcdDigits = 0o0123456789; let million = 0o1e6; ``` To fix this error, fix or remove the extra digits or letters: ```javascript let permissions = 0o755n; ``` Alternatively, convert the octal number literal into a decimal or hexadecimal number literal: ```javascript let bcdDigits = 123456789; let million = 1e6; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0048.md # E0048: unexpected characters in hex literal Hexadecimal (hex) number literals start with `0x` and can only contain digits `0` through `9` and `a` through `f` (and optionally an `n` to signify a `BigInt`). It is an error to include other letters in hex number literals: ```javascript let hungry = 0xfeedme; ``` To fix this error, fix or remove the extra digits or letters: ```javascript let hungry = 0xfeedad00d; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0049.md # E0049: binary number literal has no digits Decimal number literals start with `0b` and require at least one digit. It is an error to write `0b` with no following digits: ```javascript let mask = 0b ``` To fix this error, write digits after `0b`: ```javascript let mask = 0b1000; ``` Alternatively, remove `b` to create a `0` number literal. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0050.md # E0050: hex number literal has no digits Hexadecimal (hex) number literals start with `0x` and require at least one digit. It is an error to write `0x` with no following digits: ```javascript let mask = 0x ``` To fix this error, write digits after `0x`: ```javascript let mask = 0xff00; ``` Alternatively, remove `x` to create a `0` number literal. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0051.md # E0051: octal number literal has no digits Octal number literals start with `0o` and require at least one digit. It is an error to write `0o` with no following digits: ```javascript let mask = 0o ``` To fix this error, write digits after `0o`: ```javascript let mask = 0o700; ``` Alternatively, remove `o` to create a `0` number literal. Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0052.md # E0052: unexpected '#' ```config-for-examples { "globals": { "encrypt": true, "sendMessage": true, "synchronous": true, "blocking": true } } ``` In JavaScript, `#` is used for private properties and for shebangs at the beginning of a file (e.g. `#!/usr/bin/env node`). (`#` does not start a comment.) It is an error to use `#` anywhere else: ```javascript class Auth { #password; authenticate() { # synchronous (blocking) sendMessage(encrypt(this.# password)); } } ``` To fix this error, write the property's name after `#`, and use `//` for line comments: ```javascript class Auth { #password; authenticate() { // synchronous (blocking) sendMessage(encrypt(this.#password)); } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0053.md # E0053: missing property name between '.' and '.' ```config-for-examples { "globals": { "me": true } } ``` The `.` operator accesses an object's property. It is a syntax error to write two `.` in a row without a property name in between: ```javascript console.log(`My bestie is ${me..name}`); let favoriteLanguage = 'Lua'; console.log('I love ' .. favoriteLanguage .. '!'); ``` To fix this error, write the property name between the two `.`s: ```javascript console.log(`My bestie is ${me.bestFriend.name}`); ``` Alternatively, concatenate strings using `+` instead of `..`: ```javascript let favoriteLanguage = 'Lua'; console.log('I love ' + favoriteLanguage + '!'); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0054.md # E0054: unexpected token If you get error E0054, quick-lint-js does not understand your code for some reasons. The authors of quick-lint-js have not written a helpful message. If you encounter this error, please [submit a bug report](https://github.com/quick-lint/quick-lint-js/issues). Typically, this error occurs if code contains an operator which doesn't belong: ```javascript let person = "Sam";: ``` To fix this error, write correct JavaScript syntax: ```javascript let person = "Sam"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0055.md # E0055: unmatched indexing bracket ```config-for-examples { "globals": { "friends": true } } ``` It is an error to write the indexing operator `[` without its matching `]`: ```javascript for (let i = 0; i < friends.length; ++i) { let friend = friends[i; console.log[(`Hello, ${friend}!`); } ``` To fix this error, write the closing `]`, or remove the extraneous `[`: ```javascript for (let i = 0; i < friends.length; ++i) { let friend = friends[i]; console.log(`Hello, ${friend}!`); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0056.md # E0056: unmatched parenthesis It is an error to write the `(` without its matching `)`: ```javascript function fma(a, b, c) { return (a * b + c; } let five = (fma(2, 2, 1); ``` To fix this error, write the closing `)`, or remove the extraneous `(`: ```javascript function fma(a, b, c) { return (a * b) + c; } let five = fma(2, 2, 1); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0057.md # E0057: use of undeclared variable ```config-for-examples { "globals": { "isHappy": true } } ``` It is an error to use a function or variable without declaring it: ```javascript consol.write("Hello, world!"); const one = Math.sin(pi/2); function encrypt() { return data ^ 0x13371337; } if (isHappy) { let emotion = "happy"; } else { let emotion = "sad"; } console.log("I am " + emotion); function MyComponent({}) { let [pressed, setPressed] = useState(false); } google.charts.load('current', { packages: ['corechart'], }); ``` To fix this error, fix the name of the function or variable: ```javascript console.write("Hello, world!"); const one = Math.sin(Math.pi/2); ``` Alternatively, declare the function or variable: ```javascript function encrypt(data) { return data ^ 0x13371337; } ``` Alternatively, move the declaration of the variable into an outer scope: ```javascript let emotion; if (isHappy) { emotion = "happy"; } else { emotion = "sad"; } console.log("I am " + emotion); ``` Alternatively, import the function or variable: ```javascript import { useState } from "react"; function MyComponent({}) { let [pressed, setPressed] = useState(false); } ``` Alternatively, if the function or variable is global in your environment, [write a quick-lint-js.config file](https://quick-lint-js.com/config/). Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0058.md # E0058: variable used before declaration ```config-for-examples { "globals": { "person": true } } ``` Variables can be declared in many ways. For variables declared with `class`, `const`, or `let`, it is an error to use the variable before/above its declaration: ```javascript let firstName = person.firstName; if (firstName === "") { firstName = lastName; } let lastName = person.lastName; function printAdjacentPairs(items) { let first = true; for (let current of items) { if (!first) { console.log(previous, current); } let previous = current; first = false; } } ``` To fix this error, move the variable's declaration up above its use: ```javascript let firstName = person.firstName; let lastName = person.lastName; if (firstName === "") { firstName = lastName; } ``` Alternatively, declare the variable in an outer scope: ```javascript function printAdjacentPairs(items) { let first = true; let previous; for (let current of items) { if (!first) { console.log(previous, current); } previous = current; first = false; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0059.md # E0059: assignment to undeclared variable ```config-for-examples { "globals": { "isHappy": true } } ``` It is an error to assign to a variable without declaring it: ```javascript tau = Math.pi * 2; let emotion; if (isHappy) { emotion = "happy"; } else { emotio = "sad"; } console.log("I am " + emotion); ``` To fix this error, declare the variable using `const` or `let`: ```javascript let emotion; if (isHappy) { emotion = "happy"; } else { emotion = "sad"; } console.log("I am " + emotion); ``` Alternatively, if the variable is global in your environment, [write a quick-lint-js.config file](https://quick-lint-js.com/config/). Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0060.md # E0060: invalid hex escape sequence ```config-for-examples { "globals": { "isBlue": true } } ``` String literals and template literals can contain escape sequences, including `\x` followed by two hexadecimal digits. It is an error for `\x` to be followed by anything except two hexadecimal digits: ```javascript let gameTitle = isBlue ? 'Pok\xmon Blue' : 'Pok\xe9mon Red'; let path = 'c:\xampp\bin\apache.exe'; ``` To fix this error, complete the sequence by writing two hexadecimal digits: ```javascript let gameTitle = isBlue ? 'Pok\xe9mon Blue' : 'Pok\xe9mon Red'; ``` Alternatively, escape `\` with an extra `\`: ```javascript let path = 'c:\\xampp\\bin\\apache.exe'; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0061.md # E0061: missing name in function statement If a statement begins with the `function` keyword, the declared function must have a name. It is an error to start a statement with `function` but not give a name to the function: ```javascript function (number) { return number % 2 === 0; } ``` To fix this error, write the name of the function after the `function` keyword: ```javascript function isEven(number) { return number % 2 === 0; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0062.md # E0062: missing name or parentheses for function ```config-for-examples { "globals": { "isEven": true } } ``` If a statement begins with the `function` keyword, the declared function must have a name. It is an error to start a statement with `function` but not give a name to the function: ```javascript function() { // IIFE for our module class PublicClass {} class PrivateClass {} window.PublicClass = PublicClass; }() ``` To fix this error, wrap the IIFE (Immediately Invoked Function Expression) in parentheses: ```javascript (function() { // IIFE for our module class PublicClass {} class PrivateClass {} window.PublicClass = PublicClass; }()) ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0063.md # E0063: missing operator between expression and arrow function The left-hand side of `=>` must be a list of parameters. It is a syntax error if the left-hand side looks like a function call: ```javascript let fs = require("fs"); let path = process.argv[2]; fs.readFile(path (err, data) => { console.log(data); }); ``` To fix this error, make the left-hand side of `=>` valid by adding an operator (usually `,`) before the parameter list: ```javascript let fs = require("fs"); let path = process.argv[2]; fs.readFile(path, (err, data) => { console.log(data); }); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0064.md # E0064: missing body for 'if' statement ```config-for-examples { "globals": { "AssertionError": true, "rose": true, "sugar": true, "violet": true } } ``` `if` statements require a body, which must be a statement or `{` `}` surrounding a list of statements. It is a syntax error to omit the body of an `if` statement: ```javascript function assert(condition) { if (!condition) } if (rose.color === 'red' && violet.color === 'blue') ``` To fix this error, write the body of the `if` statement: ```javascript function assert(condition) { if (!condition) throw new AssertionError(); } if (rose.color === 'red' && violet.color === 'blue') { sugar.flavor = 'sweet'; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0065.md # E0065: 'else' has no corresponding 'if' ```config-for-examples { "globals": { "end": true, "failingTestDescription": true, "start": true, "testPassed": true } } ``` `if`-`else` statements require an `if` clause. It is a syntax error to have an `else` without a matching `if` immediately preceeding: ```javascript if (testPassed) console.log("passed!"); console.log("tests took ${end - start} s"); else { console.log("TEST FAILED:"); console.log(failingTestDescription); } ``` Note: In the above example, the second `console.log` call is not part of the `if` statement. Only the first `console.log` call is part of the `if` statement. To fix this error, make sure your `else` is properly attached to an `if`: ```javascript if (testPassed) { console.log("passed!"); console.log("tests took ${end - start} s"); } else { console.log("TEST FAILED:"); console.log(failingTestDescription); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0066.md # E0066: exporting requires '{' and '}' When exporting a class, function, or variable, you must either export while declaring or export separately from declaring. When exporting separately, it is a syntax error to write `export` followed by the name of the thing you want to export: ```javascript class Person {} export Person; ``` To fix this error, add `{` and `}` around the exported names: ```javascript class Person {} export {Person}; ``` Alternatively, write the `default` keyword after `export`: ```javascript class Person {} export default Person; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0067.md # E0067: exporting requires 'default' It is a syntax error to export an expression without using the `default` keyword: ```javascript function loadConfig() {} export loadConfig(); ``` To fix this error, add the `default` keyword to export the result of the expression as the module's default export: ```javascript function loadConfig() {} export default loadConfig(); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0068.md # E0068: extra ',' is not allowed between function call arguments In a function call, an extra `,` can be added to the end of the argument list. However, it is a syntax error to include an extra `,` in between arguments: ```javascript let name = prompt(); console.log("Hello",, name); ``` To fix this error, remove the extra `,`: ```javascript let name = prompt(); console.log("Hello", name); ``` Alternatively, write an argument between the two `,`s: ```javascript let honorific = prompt(); let name = prompt(); console.log("Hello", honorific, name); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0069.md # E0069: cannot declare 'await' inside async function ```config-for-examples { "globals": { "closeOven": true, "fs": true, "openOven": true, "pidFile": true, "takePizza": true, "visitOven": true, "waitForPizza": true } } ``` In non-strict mode, a variable can be named `await`. In strict mode and inside `async` functions, it is a syntax error to use `await` as a variable name: ```javascript-ignoring-extra-errors async function main() { const await fs.promises.writeFile( pidFile, process.pid, ); } async function getCookedPizza(await) { visitOven(); openOven(); if (await) { await waitForPizza(); } let pizza = takePizza(); closeOven(); return pizza; } ``` To fix this error, complete the variable declaration preceeding `await`: ```javascript async function main() { const pidFile = "./myapp.pid"; await fs.promises.writeFile( pidFile, process.pid, ); } ``` Alternatively, rename the variable to something other than `await`: ```javascript async function getCookedPizza(wait) { visitOven(); openOven(); if (wait) { await waitForPizza(); } let pizza = takePizza(); closeOven(); return pizza; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0070.md # E0070: commas are not allowed after spread parameter In a function declaration, an extra `,` can be added to the end of the parameter list. However, it is a syntax error to include an extra `,` after a spread parameter: ```javascript function sum( ...numbers, ) { return numbers.reduce((x, y) => x+y, 0); } ``` To fix this error, remove the extra `,`: ```javascript function sum( ...numbers ) { return numbers.reduce((x, y) => x+y, 0); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0071.md # E0071: cannot declare 'yield' inside generator function In non-strict mode, a variable can be named `yield`. In strict mode and inside generator functions, it is a syntax error to use `yield` as a variable name: ```javascript-ignoring-extra-errors function *mapRange(end, f) { for (let i = 0; i < end; ++i) { const yield item; } } ``` To fix this error, complete the variable declaration preceeding `yield`: ```javascript function *mapRange(f, end) { for (let i = 0; i < end; ++i) { const item = f(i); yield item; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0072.md # E0072: methods should not use the 'function' keyword Classes and object literals can contain methods. It is an error to use the `function` keyword in a class or object literal when defining a method: ```javascript class Doge { function speak() { console.log('many woofie'); } } ``` To fix this error, remove the `function` keyword: ```javascript class Doge { speak() { console.log('many woofie'); } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0073.md # E0073: missing function parameter list Functions declared with `function` can have zero or more parameters. It is a syntax error to omit the parameter list, including `(` and `)`, even if the function has no parameters: ```javascript class Doge { speak { console.log('many woofie'); } } function visitDogPark { new Doge().speak(); } setInterval( function { visitDogPark(); }, 1000, ); ``` To fix this error, add a pair of parentheses before `{` in the function: ```javascript class Doge { speak() { console.log('many woofie'); } } function visitDogPark() { new Doge().speak(); } setInterval( function() { visitDogPark(); }, 1000, ); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0074.md # E0074: '.' operator needs a key name; use + to concatenate strings; use [] to access with a dynamic key The right-hand side of the `.` operator must be a property name or a private property name. It is an error for `.` to be followed by a literal: ```javascript const ages = { "strager": 29, "Elon Musk": 50, }; console.log("Musk's age:", ages."Elon Musk"); const $favoriteLanguage = 'PHP'; console.log('I love ' . $favoriteLanguage); ``` To fix this error, access properties using `[` `]` instead of `.`: ```javascript const ages = { "strager": 29, "Elon Musk": 50, }; console.log("Musk's age:", ages["Elon Musk"]); ``` Alternatively, concatenate strings using `+` instead of `.`: ```javascript const $favoriteLanguage = 'PHP'; console.log('I love ' + $favoriteLanguage); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0075.md # E0075: indexing requires an expression ```config-for-examples { "globals": { "friends": true } } ``` The syntax for indexing is `expr1[expr2]`. It is an error to omit the expression between `[` and `]`: ```javascript let colorToCode = { red: '#ff0000', green: '#00ff00', blue: '#0000ff', }; let color = prompt(); document.body.style.color = colorToCode[]; let newFriends = friends[]; newFriends.push("Alice"); console.log(friends, "=>", newFriends); ``` To fix this error, write an expression between `[` and `]`: ```javascript let colorToCode = { red: '#ff0000', green: '#00ff00', blue: '#0000ff', }; let color = prompt(); document.body.style.color = colorToCode[color]; ``` Alternatively, to copy an array, create a new array and spread the old array into the new array: ```javascript let newFriends = [...friends]; newFriends.push("Alice"); console.log(friends, "=>", newFriends); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0076.md # E0076: cannot declare and export variable with 'export default' In modules, you can declare and export a variable at the same time. However, it is a syntax error to declare and export a variable by default: ```javascript export default let cache = {}; ``` To fix this error, export by name, not by default: ```javascript // Import using: // import {cache} from "./cache.mjs"; export let cache = {}; ``` Alternatively, to export by default, declare the variable then export it in a separate statement. Note that this means importers of the variable cannot assign to the variable (but the object can still be modified): ```javascript // Import using: // import cache from "./cache.mjs"; let cache = {}; export default cache; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0077.md # E0077: function call before declaration in blocked scope A function can't be called before its declaration in block scope in some JavaScript engines (including the engines used in Google Chrome and Mozilla Firefox): ```javascript f(); { function f() {} } ``` To fix this error, move the function call below the block scope in which it is declared: ```javascript { function f() {} } f(); ``` Another way to fix this error, move the function out of the block scope in which it is declared. ```javascript f(); function f() {} { } ``` OR ```javascript f(); { } function f() {} ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0078.md # E0078: missing expression between parentheses ```config-for-examples { "globals": { "eatCookies": true, "loadConfig": true, "putAwayCookieJar": true, "takeCookiesFromCookieJar": true } } ``` Parentheses (`(` and `)`) serve three purposes in JavaScript: * grouping in expressions * calling functions * function parameters It is a syntax error to write `(` immediately followed by `)` (with nothing between) when grouping in expressions: ```javascript function fma(a, b, c) { return () + c; } const config = (); takeCookiesFromCookieJar() .then(cookies => eatCookies() .then(())); ``` To fix this error, write an expression between the parentheses: ```javascript function fma(a, b, c) { return (a*b) + c; } ``` Alternatively, put the name of a function before the parentheses to call a function with no arguments: ```javascript const config = loadConfig(); ``` Alternatively, write the rest of your arrow function: ```javascript takeCookiesFromCookieJar() .then(cookies => eatCookies() .then(() => putAwayCookieJar())); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0079.md # E0079: missing name of exported function ```config-for-examples { "globals": { "React": true } } ``` In modules, functions can be exported by name or by default. It is an error to export an unnamed function by name: ```javascript export function({props}) { return React.createElement( "h1", null, `Hello, ${props.name}!`, ); } ``` To fix this error, export the function by default: ```javascript // Import using: // import MyComponent from "./MyComponent.mjs"; export default function({props}) { return React.createElement( "h1", null, `Hello, ${props.name}!`, ); } ``` Alternatively, give a name to the function: ```javascript // Import using: // import {MyComponent} from "./MyComponent.mjs"; export function MyComponent({props}) { return React.createElement( "h1", null, `Hello, ${props.name}!`, ); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0080.md # E0080: missing name of class If a statement begins with the `class` keyword, the declared class must have a name. It is a syntax error to start a statement with `class` but not give a name to the class: ```javascript class { speak() { console.log('woof!'); } } ``` To fix this error, write the name of the class after the `class` keyword: ```javascript class Doggie { speak() { console.log('woof!'); } } ``` Alternatively, declare a variable and initialize it with the class: ```javascript const Doggie = class { speak() { console.log('woof!'); } }; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0081.md # E0081: missing name of exported class ```config-for-examples { "globals": { "React": true } } ``` In modules, classes can be exported by name or by default. It is an error to export an unnamed class by name: ```javascript export class { render() { return React.createElement( "h1", null, `Hello, ${this.props.name}!`, ); } } ``` To fix this error, export the class by default: ```javascript // Import using: // import MyComponent from "./MyComponent.mjs"; export default class { render() { return React.createElement( "h1", null, `Hello, ${this.props.name}!`, ); } } ``` Alternatively, give a name to the class: ```javascript // Import using: // import {MyComponent} from "./MyComponent.mjs"; export class MyComponent { render() { return React.createElement( "h1", null, `Hello, ${this.props.name}!`, ); } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0082.md # E0082: assigning to 'async' in a for-of loop requires parentheses If a variable is named `async`, it is a syntax error to assign to that variable in a `for`-`of` loop: ```javascript async function awaitSequentially(asyncs) { let results = []; let async; for (async of asyncs) { results.push(await async); } return results; } ``` To fix this error, declare the variable inside the `for`-`of` loop: ```javascript async function awaitSequentially(asyncs) { let results = []; for (let async of asyncs) { results.push(await async); } return results; } ``` Alternatively, rename the variable to something other than `async`: ```javascript async function awaitSequentially(promises) { let results = []; let promise; for (promise of promises) { results.push(await promise); } return results; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0083.md # E0083: missing value for object property ```config-for-examples { "globals": { "React": true, "children": true, "classes": true } } ``` Object literals support a short-hand syntax which allows you to omit the value of a property. It is a syntax error to omit the value if the key is computed or is a keyword: ```javascript let class_ = classes.join(" "); React.createElement( 'div', { class }, children, ); ``` To fix this error, explicitly write a value for the property: ```javascript let class_ = classes.join(" "); React.createElement( 'div', { class: class_ }, children, ); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0084.md # E0084: do-while loop needs parentheses around condition `do`-`while` loops have a condition after the `while` keyword. It is a syntax error to write a condition without `(` and `)`: ```javascript let name; do { name = prompt('What is your name?'); } while name === ''; ``` To fix this error, write `(` before the condition and `)` after the condition: ```javascript let name; do { name = prompt('What is your name?'); } while (name === ''); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0085.md # E0085: do-while loop is missing '(' or ')' around condition `do`-`while` loops have a condition after the `while` keyword. It is a syntax error to write a condition without either `(` or `)`: ```javascript let name; do { name = prompt('What is your name?'); } while (name === ''; ``` To fix this error, write `(` before the condition or `)` after the condition: ```javascript let name; do { name = prompt('What is your name?'); } while (name === ''); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0086.md # E0086: redundant delete statement on variable The following delete statement is redundant on variable: ```javascript let x = 3; delete x; console.log(x); ``` To fix this warning, remove the delete statement: ```javascript let x = 3; console.log(x); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0087.md # E0087: while loop needs parentheses around condition `while` loops have a condition after the `while` keyword. It is a syntax error to write a condition without `(` and `)`: ```javascript let name = ''; while name === '' { name = prompt('What is your name?'); } ``` To fix this error, write `(` before the condition and `)` after the condition: ```javascript let name = ''; while (name === '') { name = prompt('What is your name?'); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0088.md # E0088: while loop is missing '(' or ')' around condition `while` loops have a condition after the `while` keyword. It is a syntax error to write a condition without either `(` or `)`: ```javascript let name = ''; while (name === '' { name = prompt('What is your name?'); } ``` To fix this error, write `(` before the condition or `)` after the condition: ```javascript let name = ''; while (name === '') { name = prompt('What is your name?'); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0089.md # E0089: with statement needs parentheses around expression ```config-for-examples { "globals": { "person": true } } ``` `with` statements have an expression after the `with` keyword. It is a syntax error to write an expression without `(` and `)`: ```javascript with person { console.log(`Hi, ${firstName} ${lastName}!`); } ``` To fix this error, write `(` before the expression and `)` after the expression: ```javascript with (person) { console.log(`Hi, ${firstName} ${lastName}!`); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0090.md # E0090: with statement is missing '(' or ')' around expression ```config-for-examples { "globals": { "person": true } } ``` `with` statements have an expression after the `with` keyword. It is a syntax error to write an expression without either `(` or `)`: ```javascript with (person { console.log(`Hi, ${firstName} ${lastName}!`); } ``` To fix this error, write `(` before the expression or `)` after the expression: ```javascript with (person) { console.log(`Hi, ${firstName} ${lastName}!`); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0091.md # E0091: switch statement needs parentheses around condition `switch` statements have a condition after the `switch` keyword. It is a syntax error to write a condition without `(` and `)`: ```javascript function colorToHexCode(color) { switch color { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` To fix this error, write `(` before the condition and `)` after the condition: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0092.md # E0092: switch statement is missing '(' or ')' around condition `switch` statements have a condition after the `switch` keyword. It is a syntax error to write a condition without either `(` or `)`: ```javascript function colorToHexCode(color) { switch (color { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` To fix this error, write `(` before the condition or `)` after the condition: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0093.md # E0093: C-style for loop is missing its third component C-style `for` loops have three components, each separated by `;`: an initializer, a condition expression, and an update expression. It is a syntax error to write only two of these three components: ```javascript for (let i = 0; i < 100) { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, write the missing component: ```javascript for (let i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0094.md # E0094: missing body for 'for' loop ```config-for-examples { "globals": { "isDigit": true } } ``` C-style `for` loops, `for`-`in` loops, and `for`-`of` loops require a body, which must be a statement or `{` `}` surrounding a list of statements. It is a syntax error to omit the body of a `for` loop: ```javascript function skipNumber(parser) { for (; parser.isDigit(); parser.next()) } ``` To fix this error, write the body of the `for` loop: ```javascript function skipNumber(parser) { for (; parser.isDigit(); parser.next()) {} } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0095.md # E0095: Unicode byte order mark (BOM) cannot appear before #! at beginning of script A script cannot have Unicode byte order mark (BOM) before `#!` ```javascript #!/usr/bin/env node let x = 3; console.log(x); ``` To fix this error, remove the Unicode BOM before `#!` ```javascript #!/usr/bin/env node let x = 3; console.log(x); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0096.md # E0096: missing for loop header ```config-for-examples { "globals": { "benchmark": true, "collectBenchmarks": true, "runBenchmark": true } } ``` It is a syntax error to have nothing between the `(` and `)` in a `for` loop: ```javascript for () { runBenchmark(benchmark); } ``` To fix this error, continue writing the `for` loop: ```javascript for (const benchmark of collectBenchmarks()) { runBenchmark(benchmark); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0097.md # E0097: for loop needs an iterable, or condition and update clauses ```config-for-examples { "globals": { "queue": true, "process": true } } ``` There are three kinds of `for` loops: C-style `for` loops (`;`), `for`-`in` loops, and `for`-`of` loops. It is a syntax error to write a `for` loop without `;`, `in`, or `of`: ```javascript for (queue.length > 0) { process(queue.pop()); } ``` To fix this error, use a `while` loop instead of a `for` loop: ```javascript while (queue.length > 0) { process(queue.pop()); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0098.md # E0098: for loop needs an iterable, or condition and update clauses ```config-for-examples { "globals": { "collidedEntities": true, "damage": true } } ``` There are three kinds of `for` loops: C-style `for` loops (`;`), `for`-`in` loops, and `for`-`of` loops. It is a syntax error to write a `for` loop without `;`, `in`, or `of`: ```javascript for (const enemy) { enemy.health -= damage; } for (let i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, write `in` or `of` followed by an iterable (such as an array): ```javascript for (const enemy of collidedEntities) { enemy.health -= damage; } ``` Alternatively, write the remainder of the C-style `for` loop: ```javascript for (let i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0099.md # E0099: missing semicolon between init and condition parts of for loop C-style `for` loops require two semicolons: one `;` between the init and the condition, and one `;` between the condition and the update expression. It is a syntax error to omit the `;` between the init and the condition: ```javascript let i; for (i = 0 i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, insert a semicolon (`;`) before the condition: ```javascript let i; for (i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0100.md # E0100: missing semicolon between condition and update parts of for loop C-style `for` loops require two semicolons: one `;` between the init and the condition, and one `;` between the condition and the update expression. It is a syntax error to omit the `;` between the condition and the update expression: ```javascript for (let i = 0; i < 100 ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, insert a semicolon (`;`) after the condition: ```javascript for (let i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0101.md # E0101: missing body for do-while loop ```config-for-examples { "globals": { "isDigit": true, "queue": true } } ``` `do`-`while` loops require a body, which must be a statement or `{` `}` surrounding a list of statements. It is a syntax error to omit the body of a `do`-`while` loop: ```javascript function skipNumber(parser) { do while (isDigit(parser.peek())); } do while (queue.length > 0) { queue.pop().run(); } ``` To fix this error, write the body of the `do`-`while` loop: ```javascript function skipNumber(parser) { do parser.next(); while (isDigit(parser.peek())); } ``` Alternatively, remove the extraneous `do` keyword: ```javascript while (queue.length > 0) { queue.pop().run(); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0102.md # E0102: C-style for loops have only three semicolon-separated components ```config-for-examples { "globals": { "width": true, "height": true, "draw": true, "pixelAt": true } } ``` C-style `for` loops have three components, each separated by `;`: an initializer, a condition expression, and an update expression. It is a syntax error to write more than three components: ```javascript for (let x = 0, y = 0; x < width && y < height; ++x; ++y) { draw(x, y, pixelAt(x, y)); } ``` To fix this error, use `,` instead of `;` to separate expressions in the update clause: ```javascript for (let x = 0, y = 0; x < width && y < height; ++x, ++y) { draw(x, y, pixelAt(x, y)); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0103.md # E0103: missing 'while (condition)' for do-while statement A `do`-`while` loop has three parts: the `do` keyword, a body (a statement, or a list of statements surrounded by `{` and `}`), and the `while` part including the condition. It is a syntax error to write the `do` keyword without the `while` part: ```javascript let name; do { name = prompt('What is your name?'); }; while (name === ''); ``` To fix this error, make sure there is nothing between the loop's body and the `while` keyword: ```javascript let name; do { name = prompt('What is your name?'); } while (name === ''); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0104.md # E0104: missing body for while loop ```config-for-examples { "globals": { "isDigit": true, "isSorted": true, "shuffle": true } } ``` `while` loops require a body, which must be a statement or `{` `}` surrounding a list of statements. It is a syntax error to omit the body of a `while` loop: ```javascript function bogoSort(array) { while (!isSorted(array)) } function skipNumber(parser) { { parser.next(); } while (isDigit(parser.peek())) } ``` To fix this error, write the body of the `while` loop: ```javascript function bogoSort(array) { while (!isSorted(array)) shuffle(array); } ``` Alternatively, make the `while` loop a `do`-`while` loop: ```javascript function skipNumber(parser) { do { parser.next(); } while (isDigit(parser.peek())) } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0105.md # E0105: missing parameters for arrow function Arrow functions need a parameter list. It is a syntax error to omit the parameter list before `=>`, even if the arrow function takes no parameters: ```javascript setInterval(=> { console.log("it is now", new Date()); }, 1000); ``` To fix this error, write an empty parameter list before `=>`: ```javascript setInterval(() => { console.log("it is now", new Date()); }, 1000); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0106.md # E0106: missing body for 'switch' statement `switch` statements require a body, which must be a list of statements surrounded by `{` and `}`. It is a syntax error to omit the body of an `switch` statement: ```javascript function colorToHexCode(color) { switch (color) } ``` To fix this error, write the body of the `switch` statement: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0107.md # E0107: expected '{' A `switch` statement has a list of cases. It is a syntax error to omit `{` after the condition of a `switch` statement: ```javascript function colorToHexCode(color) { switch (color) case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` To fix this error insert a `{` after the condition: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0108.md # E0108: 'in' disallowed in C-style for loop initializer ```config-for-examples { "globals": { "data": true, "opts": true, "processItem": true } } ``` C-style `for` loops can have a expression the first `;`-separated part. It is an error for the expression to use the `in` operator without parentheses: ```javascript for (let i = 'startAtOne' in opts ? 1 : 0; i < opts.count; ++i) { if (!processItem(data[i])) { break; } } ``` To fix this error, surround the `in` expression with parentheses: ```javascript for (let i = ('startAtOne' in opts) ? 1 : 0; i < opts.count; ++i) { if (!processItem(data[i])) { break; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0109.md # E0109: for-of loop expression cannot have semicolons ```config-for-examples { "globals": { "collectBenchmarks": true, "runBenchmark": true } } ``` There are three kinds of `for` loops: C-style `for` loops (`;`), `for`-`in` loops, and `for`-`of` loops. It is a syntax error to write a `for`-`of` loop with a `;`: ```javascript for (let i of 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } for (const benchmark of collectBenchmarks();) { runBenchmark(benchmark); } ``` To fix this error, remove the `of` keyword in the C-style `for` loop: ```javascript for (let i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Alternatively, remove the extra `;`: ```javascript for (const benchmark of collectBenchmarks()) { runBenchmark(benchmark); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0110.md # E0110: for-in loop expression cannot have semicolons ```config-for-examples { "globals": { "collectBenchmarks": true, "runBenchmark": true } } ``` There are three kinds of `for` loops: C-style `for` loops (`;`), `for`-`in` loops, and `for`-`of` loops. It is a syntax error to write a `for`-`in` loop with a `;`: ```javascript for (let i in 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } let benchmarks = collectBenchmarks(); for (const name in benchmarks;) { runBenchmark(name, benchmarks[name]); } ``` To fix this error, remove the `in` keyword in the C-style `for` loop: ```javascript for (let i = 0; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Alternatively, remove the extra `;`: ```javascript let benchmarks = collectBenchmarks(); for (const name in benchmarks) { runBenchmark(name, benchmarks[name]); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0111.md # E0111: missing body for class ```config-for-examples { "globals": { "parseConfig": true } } ``` Classes require a body, which must be a list of properties and methods surrounded by `{` and `}`. It is a syntax error to omit the body of a class: ```javascript class Animal {} class Doge extends Animal class Kitty extends Animal ``` To fix this error, write the body of the class, including `{` and `}`: ```javascript class Animal {} class Doge extends Animal {} class Kitty extends Animal {} ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0112.md # E0112: unexpected token in export; expected 'export default ...' or 'export {name}' or 'export * from ...' or 'export class' or 'export function' or 'export let' ```config-for-examples { "globals": { "Benchmark": true, "registerBenchmark": true } } ``` It is a syntax error to write the `export` keyword without anything following: ```javascript class SmallBenchmark extends Benchmark {} export {SmallBenchmark}; class BigBenchmark extends Benchmark {} export for (let benchmark of [new SmallBenchmark(), new BigBenchmark()]) { registerBenchmark(benchmark); } ``` To fix this error, complete the `export` statement: ```javascript class SmallBenchmark extends Benchmark {} export {SmallBenchmark}; class BigBenchmark extends Benchmark {} export {BigBenchmark}; for (let benchmark of [new SmallBenchmark(), new BigBenchmark()]) { registerBenchmark(benchmark); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0113.md # E0113: incomplete export; expected 'export default ...' or 'export {name}' or 'export * from ...' or 'export class' or 'export function' or 'export let' ```config-for-examples { "globals": { "Benchmark": true, "registerBenchmark": true } } ``` It is a syntax error to write the `export` keyword without anything following: ```javascript class SmallBenchmark extends Benchmark {} export {SmallBenchmark}; class BigBenchmark extends Benchmark {} export ``` To fix this error, complete the `export` statement: ```javascript class SmallBenchmark extends Benchmark {} export {SmallBenchmark}; class BigBenchmark extends Benchmark {} export {BigBenchmark}; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0114.md # E0114: unexpected token in variable declaration; expected variable name ```config-for-examples { "globals": { "doMoreWork": true, "done": true } } ``` Variables can be declared using a keyword such as `const`, `let`, or `var`. It is a syntax error write anything except a variable name or a destructuring pattern in a `const`, `let`, or `var` declaration: ```javascript let sawFizzBuzz, 100..toRange().forEach(i => { if (i % 15) { console.log(i); } else { console.log("FizzBuzz"); sawFizzBuzz = true; } }); let while (!done) { doMoreWork(); } ``` To fix this error, replace `,` with `;`: ```javascript let sawFizzBuzz; 100..toRange().forEach(i => { if (i % 15) { console.log(i); } else { console.log("FizzBuzz"); sawFizzBuzz = true; } }); ``` Alternatively, remove the extra `const`, `let`, or `var` keyword: ```javascript while (!done) { doMoreWork(); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0115.md # E0115: unexpected 'case' outside switch statement `switch` statements can contain `case` labels. It is a syntax error to write a `case` label outside a `switch` statement: ```javascript function colorToHexCode(color) { switch (color) { } case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } ``` To fix this error, move the `case` label into a `switch` statement: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0116.md # E0116: unexpected 'default' outside switch statement `switch` statements can contain a `default` label. It is a syntax error to write a `default` label outside a `switch` statement: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } default: throw new Error(`unknown color ${color}`); } ``` To fix this error, move the `default` label into a `switch` statement: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; default: throw new Error(`unknown color ${color}`); } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0117.md # E0117: unexpected 'catch' without 'try' ```config-for-examples { "globals": { "fs": true, "parseConfig": true } } ``` `try` statements can have a `catch` clause. It is a syntax error to have a `catch` clause with no corresponding `try` statement: ```javascript-ignoring-extra-errors async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); }; catch (error) { if (error.code === 'ENOENT') { return {}; } else { throw error; } } } ``` To fix this error, make sure the `catch` keyword immediately follows the `}` for a `try` block: ```javascript async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } catch (error) { if (error.code === 'ENOENT') { return {}; } else { throw error; } } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0118.md # E0118: unexpected 'finally' without 'try' `try` statements can have a `finally` clause. It is a syntax error to have a `finally` clause with no corresponding `try` statement: ```javascript-ignoring-extra-errors let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); }; finally { recursionDepth -= 1; } } ``` To fix this error, make sure the `finally` keyword immediately follows the `}` for a `try` block or a `catch` block: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } finally { recursionDepth -= 1; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0119.md # E0119: missing body for catch clause ```config-for-examples { "globals": { "parseConfig": true } } ``` `catch` clauses in `try` statements require a body, which must be a list of statements surrounded by `{` and `}`. It is a syntax error to omit the body of a `catch` clause: ```javascript const fs = require("fs"); async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } catch (error) } ``` To fix this error, write the body of the `catch` statement, including `{` and `}`: ```javascript const fs = require("fs"); async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } catch (error) { if (error.code === 'ENOENT') { return {}; } else { throw error; } } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0120.md # E0120: missing body for try statement `try` statements require a body, which must be a list of statements surrounded by `{` and `}`. It is a syntax error to omit the body of a `try` statement: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try finally { recursionDepth -= 1; } } ``` To fix this error, write the body of the `try` statement: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } finally { recursionDepth -= 1; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0121.md # E0121: missing body for finally clause `finally` clauses in `try` statements require a body, which must be a list of statements surrounded by `{` and `}`. It is a syntax error to omit the body of a `finally` clause: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } finally } ``` To fix this error, write the body of the `finally` statement, including `{` and `}`: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } finally { recursionDepth -= 1; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0122.md # E0122: missing catch or finally clause for try statement ```config-for-examples { "globals": { "fs": true, "parseConfig": true } } ``` A `try` statement has a list of statements followed by an optional `catch` block followed by an optional `finally` block. It is a syntax error to omit both the `catch` block and the `finally` block: ```javascript async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } } let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } } ``` To fix this error, remove the `try` keyword: ```javascript async function readConfig(configFilePath) { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } ``` Alternatively, add a `catch` block after the `try` block: ```javascript async function readConfig(configFilePath) { try { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } catch (error) { if (error.code === 'ENOENT') { return {}; } else { throw error; } } } ``` Alternatively, add a `finally` block after the `try` block: ```javascript let recursionDepth = 0; function recursionExample() { if (recursionDepth > 100) { throw new Error("too much recursion!"); } recursionDepth += 1; try { recursionExample(); } finally { recursionDepth -= 1; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0123.md # E0123: missing variable name ```config-for-examples { "globals": { "bananas": true, "getBananas": true } } ``` You can declare a variable with `const`, `let`, or `var`. It is a syntax error to use `const`, `let` (in some cases), or `var` without mentioning a variable name: ```javascript const = getBananas(); console.log(bananas[0].peel()); for (let i,= 1; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, write a variable name: ```javascript const banans = getBananas(); console.log(bananas[0].peel()); ``` Alternatively, remove the extra `,`: ```javascript for (let i = 1; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0124.md # E0124: cannot declare variable named keyword It is a syntax error to declare a variable named certain keywords like `debugger` or `while`: ```javascript-ignoring-extra-errors function parseVar(s) { let var = s.split()[0]; let value = s.split()[1]; return {var, value}; } ``` To fix this error, pick a different variable name: ```javascript function parseVar(s) { let varName = s.split()[0]; let value = s.split()[1]; return {varName, value}; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0125.md # E0125: missing header and body for 'for' loop ```config-for-examples { "globals": { "collectBenchmarks": true, "runBenchmark": true } } ``` It is a syntax error to write a `for` loop without a header (in parentheses) or a body: ```javascript for let i = 1; i < 100; ++i { console.log(i % 15 ? i : "FizzBuzz"); } ``` To fix this error, put parentheses around the `for` loop's header: ```javascript for (let i = 1; i < 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0126.md # E0126: expected 'as' between '\*' and variable You can import all of a module's exports using `import *`. It is a syntax error to omit the `as` keyword between the `*` and the new object's name: ```javascript import * d3 from 'd3'; ``` To fix this error, write `as` after `*`: ```javascript import * as d3 from 'd3'; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0127.md # E0127: TypeScript's 'enum' feature is not allowed in JavaScript JavaScript does not support TypeScript-style enums. It is a syntax error to declare an enum: ```javascript enum Color { BLUE, GREEN, RED, } const favoriteColor = Color.BLUE; ``` To fix this error, write an object instead: ```javascript const Color = { BLUE: 0, GREEN: 1, RED: 2, }; const favoriteColor = Color.BLUE; ``` Alternatively, declare separate variables: ```javascript const Color_BLUE = 0; const Color_GREEN = 1; const Color_RED = 2; const favoriteColor = Color_BLUE; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0128.md # E0128: expected 'from' before module specifier `import` statements load things from other files. It is a syntax error to omit the `from` keyword before the module name: ```javascript import React, {createElement} 'react'; ``` To fix this error, write the `from` keyword before the module name: ```javascript import React, {createElement} from 'react'; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0129.md # E0129: expected 'from "name_of_module.mjs"' `import` statements load things from other files. It is a syntax error to omit the name of the module being imported: ```javascript import React, {createElement}; ``` To fix this error, write the `from` keyword followed by the module name: ```javascript import React, {createElement} from 'react'; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0130.md # E0130: missing catch variable name between parentheses ```config-for-examples { "globals": { "downloadURL": true } } ``` A `try` statement can have a `catch` clause. The `catch` clause can define a variable for the caught exception. It is a syntax error to omit the variable name between a `catch` clause's parentheses: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch () { // Loop and try again. } } } ``` To fix this error, remove the parentheses: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch { // Loop and try again. } } } ``` Alternatively, write a variable name between the parentheses: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch (e) { console.log(`retrying: ${e}`); } } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0131.md # E0131: expected ',' between object literal entries ```config-for-examples { "globals": { "axios": true, "cachingAdapter": true, "url": true } } ``` In an object literal, entries are separated with a `,`. It is a syntax error to separate entries with `;` instead: ```javascript let response = await axios.get(url.toString(), { adapter: cachingAdapter; validateStatus(_status) { return true; }; responseType: "stream" }); ``` To fix this error, replace `;` with `,`: ```javascript let response = await axios.get(url.toString(), { adapter: cachingAdapter, validateStatus(_status) { return true; }, responseType: "stream" }); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0132.md # E0132: missing ',' between variable declarations ```config-for-examples { "globals": { "p": true, "pi": true } } ``` A `const`, `let`, and `var` statement can declare multiple variables. It is a syntax error to omit a `,` between declared variables: ```javascript const x=p.x y=p.y; let tau = 2 pi; ``` Fix this this error, write a `,` before the second variable's name: ```javascript const x=p.x, y=p.y; ``` Alternatively, use the `*` operator to multiply a variable by a number: ```javascript let tau = 2*pi; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0133.md # E0133: error generator function star belongs before name The following code has misplaced '*'. ```javascript *function f(x) { yield x; } ``` To fix this error, move the '*' before function name. ```javascript function *f(x) { yield x; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0134.md # E0134: unclosed code block; expected '}' by end of file ```config-for-examples { "globals": { "doWork": true, "work": true } } ``` Every `{` introducing a code block must have a matching `}` ending a code block. It is a syntax error to omit the `}`: ```javascript function doAllWork() { while (work.length) { doWork(work.pop()); } ``` To fix this error, write a matching `}`: ```javascript function doAllWork() { while (work.length) { doWork(work.pop()); } } ``` Alternatively, remove an unnecessary `{`: ```javascript function doAllWork() { while (work.length) doWork(work.pop()); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0135.md # E0135: expected variable name for 'catch' ```config-for-examples { "globals": { "downloadURL": true } } ``` A `try` statement can have a `catch` clause. The `catch` clause can define a variable for the caught exception. It is a syntax error to write a string literal instead of a variable name between a `catch` clause's parentheses: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch ('ETIMEOUT') { // Loop and try again. } } } ``` To fix this error, replace the string literal with a variable name: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch (e) { if (e.code === 'ETIMEOUT') { // Loop and try again. } else { throw e; } } } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0136.md # E0136: cannot update variable with '+=' while declaring it ```config-for-examples { "globals": { "x": true, "y": true, "z": true } } ``` When declaring a variable with `const`, `let`, or `var`, you can set the variable's initial value using `=`. It is a syntax error to use a compound assignment operator instead of `=`: ```javascript let i = 0; while (i < 100) { let i += 1; console.log(i % 15 ? i : "FizzBuzz"); } const length *= Math.sqrt(x*x + y*y + z*z); ``` To fix this error, remove the `let` keyword: ```javascript let i = 0; while (i < 100) { i += 1; console.log(i % 15 ? i : "FizzBuzz"); } ``` Alternatively, replace the compound assignment operator with `=`: ```javascript const length = Math.sqrt(x*x + y*y + z*z); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0137.md # E0137: missing condition for switch statement A `switch` statement has a condition which determines which `case` or `default` label to execute. It is an error to omit a `switch`'s condition: ```javascript function colorToHexCode(color) { switch { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` To fix this error, write the condition with parentheses after the `switch` keyword: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0138.md # E0138: missing condition for if statement ```config-for-examples { "globals": { "person": true } } ``` An `if` statement has a condition which determines whether the body will execute or not. It is an error to omit an `if` statement's condition: ```javascript let firstName = person.firstName; let lastName = person.lastName; if { firstName = lastName; } ``` To fix this error, write the condition with parentheses after the `if` keyword: ```javascript let firstName = person.firstName; let lastName = person.lastName; if (firstName === "") { firstName = lastName; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0139.md # E0139: missing condition for while statement ```config-for-examples { "globals": { "downloadURL": true } } ``` A `while` statement has a condition which determines whether the body will execute or not. It is an error to omit a `while` statement's condition: ```javascript let name = ''; while { name = prompt('What is your name?'); } async function downloadURLWithRetries(url) { while { try { return await downloadURL(url); } catch { // Loop and try again. } } } ``` To fix this error, write the condition with parentheses after the `if` keyword: ```javascript let name = ''; while (name === '') { name = prompt('What is your name?'); } ``` Alternatively, to write an infinite loop, write `for (;;)` instead of `while`: ```javascript async function downloadURLWithRetries(url) { for (;;) { try { return await downloadURL(url); } catch { // Loop and try again. } } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0140.md # E0140: expected expression after 'case' A `switch` statement has a list of cases, each beginning with either the `case` keyword or the `default` keyword. It is a syntax error to omit an expression after the `case` keyword: ```javascript function getText(node) { switch (node.nodeType) { case document.TEXT_NODE: return node.nodeValue; case: { let result = ""; for (let child of node.childNodes) { result += getText(child, document); } return result; } default: throw new Error("Unsupported DOM node type"); } } function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; case: throw new Error(`unknown color ${color}`); } } ``` To fix this error, write an expression (usually a constant) after the `case` keyword: ```javascript function getText(node) { switch (node.nodeType) { case document.TEXT_NODE: return node.nodeValue; case document.ELEMENT_NODE: { let result = ""; for (let child of node.childNodes) { result += getText(child, document); } return result; } default: throw new Error("Unsupported DOM node type"); } } ``` Alternatively, replace the `case` keyword with `default` if the code should execute if no other `case` would: ```javascript function colorToHexCode(color) { switch (color) { case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; default: throw new Error(`unknown color ${color}`); } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0141.md # E0141: expected ')' to close function call ```config-for-examples { "globals": { "iterationCount": true, "runBenchmarkIteration": true } } ``` A function call requires a list of arguments surrounded by `(` and `)`. It is a syntax error to omit the final `)` in a function call: ```javascript for (let i = 0; i < iterationCount; ++i) { console.log("starting iteration", i, "..."; runBenchmarkIteration(); console.log("finished iteration", i); } ``` To fix this error, write the closing `)`: ```javascript for (let i = 0; i < iterationCount; ++i) { console.log("starting iteration", i, "..."); runBenchmarkIteration(); console.log("finished iteration", i); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0142.md # E0142: missing property name after '.' operator ```config-for-examples { "globals": { "goNuts": true } } ``` The `.` operator accesses an object's property. It is a syntax error to omit a property name after the `.` operator: ```javascript try { goNuts(); } catch { console.("couldn't handle deez nuts"); } ``` To fix this error, write the property name after the `.`: ```javascript try { goNuts(); } catch { console.error("couldn't handle deez nuts"); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0143.md # E0143: unmatched '}' ```config-for-examples { "globals": { "doWork": true, "work": true } } ``` Every `{` introducing a code block must have a matching `}` ending a code block. It is a syntax error to omit the `{`: ```javascript function doAllWork() { while (work.length) doWork(work.pop()); } } ``` To fix this error, write `{` to begin the code block: ```javascript function doAllWork() { while (work.length) { doWork(work.pop()); } } ``` Alternatively, remove the unnecessary `}`: ```javascript function doAllWork() { while (work.length) doWork(work.pop()); } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0144.md # E0144: cannot export variable named keyword An `export` statement can export a list of classes, functions, and variables. It is a syntax error to export something with the same name as a keyword: ```javascript // Import using: // import {class as makeClass} from "./css.mjs"; function cssClass(classes) { return Object.keys(classes).join(" "); } export {class}; ``` To fix this error, use `as` to name the export different from the declared class, function, or variable, and ensure importers use the exported name: ```javascript // Import using: // import {class as makeClass} from "./css.mjs"; function cssClass(classes) { return Object.keys(classes).join(" "); } export {cssClass as class}; ``` Alternatively, fix the name of the export, and ensure importers use the fixed name: ```javascript // Import using: // import {cssClass as makeClass} from "./css.mjs"; function cssClass(classes) { return Object.keys(classes).join(" "); } export {cssClass}; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0145.md # E0145: cannot import variable named keyword An `import` statement can import a list of classes, functions, and variables. It is a syntax error to import something with the same name as a keyword: ```javascript // Exported using: export {cssClass as class}; import {class} from "./css.mjs"; ``` To fix this error, use `as` to name the imported variable different from the exported name: ```javascript // Exported using: export {cssClass as class}; import {class as makeClass} from "./css.mjs"; ``` Alternatively, change the name of the export, and ensure other importers use the new name: ```javascript // Exported using: export {cssClass}; import {cssClass} from "./css.mjs"; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0146.md # E0146: missing ':' in conditional expression ```config-for-examples { "globals": { "focus": true } } ``` The `? :` ternary operator has three parts: the condition, the expression if true, and the expression if false. It is a syntax error to omit the expression if false: ```javascript for (let i = 1; i <= 100; ++i) { console.log(i % 15 ? i); } document.querySelector("form input")?focus(); ``` To fix this error, write `:` followed by an expression: ```javascript for (let i = 1; i <= 100; ++i) { console.log(i % 15 ? i : "FizzBuzz"); } ``` Alternatively, write `?.` instead of `?` to access an object's property: ```javascript document.querySelector("form input")?.focus(); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0147.md # E0147: unexpected identifier in expression; missing operator before ```config-for-examples { "globals": { "add": true, "dos": true, "two": true } } ``` It is an error to write two variable names without an operator in between: ```javascript const quatro = (dos dos); const four = add(two two); ``` To fix this error, remove one of the variables, or add an operator: ```javascript const quatro = (dos + dos); const four = add(two, two); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0148.md # E0148: missing body for statement; a function statement is not allowed as the body of statement ```config-for-examples { "globals": { "config": true } } ``` `do`-`while` loops, `for` loops, `while` loops, and `with` statements require a statement or list of statements for the body. It is a syntax error to write a function as the body of such a statement: ```javascript let flavors = []; for (let flavor in config.sweets) function getFavoriteFlavor() { return "chocolate"; } ``` To fix this error, write the body of the `do`-`while` loop, `for` loop, `while` loop, or `with` statement: ```javascript let flavors = []; for (let flavor in config.sweets) { flavors.push(flavor); } function getFavoriteFlavor() { return "chocolate"; } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0149.md # E0149: missing body for statement; a class statement is not allowed as the body of statement ```config-for-examples { "globals": { "config": true } } ``` `do`-`while` loops, `if` statements, `for` loops, `while` loops, `with` and labelled statements require a statement or list of statements for the body. It is a syntax error to write a class as the body of such a statement: ```javascript let flavors = []; for (let flavor in config.sweets) class SweetsBasket { /* ... */ } ``` To fix this error, write the body of the `do`-`while` loop, `if` statements, `for` loop, `while` loop, or `with` statement: ```javascript let flavors = []; for (let flavorName in config.sweets) { flavors.push(flavorName); } class SweetsBasket { /* ... */ } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0150.md # E0150: missing body for statement; a lexical declaration is not allowed as the body of statement ```config-for-examples { "globals": { "config": true, "random": true } } ``` `do`-`while` loops, `if` statements, `for` loops, `while` loops, `with` and labelled statements require a statement or list of statements for the body. It is a syntax error to declare a variable with `const` or `let` as the body of such a statement: ```javascript let flavors = []; for (let flavor in config.sweets) let favoriteFlavor = random.pick(flavors); ``` To fix this error, write the body of the `do`-`while` loop, `if` statements, `for` loop, `while` loop, or `with` statement: ```javascript let flavors = []; for (let flavorName in config.sweets) { flavors.push(flavorName); } let favoriteFlavor = random.pick(flavors); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0151.md # E0151: invalid function parameter ```config-for-examples { "globals": { "classes": true, "delimiter": true, "join": true } } ``` A function parameter can be a variable name, an array destructuring, or an object destructuring. It is a syntax error for a function parameter to look like a function call or any other expression: ```javascript const join = (string, delimiter += ",") => string.join(delimiter); function cssClass(classes()) { return join(Object.keys(classes), " "); } ``` To fix this error, write `=` to make a parameter have a default value: ```javascript const join = (string, delimiter = ",") => string.join(delimiter); ``` Alternatively, remove the parentheses indicating a function call: ```javascript function cssClass(classes) { return join(Object.keys(classes), " "); } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0152.md # E0152: legacy octal literals may not contain underscores A legacy octal literal is a `0` digit followed by one or more octal digits (`0` through `7`). It is a syntax error for a legacy octal literal to contain a digit separator (`_`): ```javascript let fileMode = 01_755; ``` To fix this error, begin the literal with `0o`: ```javascript let fileMode = 0o1_755; ``` Alternatively, remove the underscore: ```javascript let fileMode = 01755; ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0153.md # E0153: forwarding exports are only allowed in export-from An `export` statement can forward exports from another module. It is a syntax error to forward exports without specifying which module to import from: ```javascript export {"React"}; ``` To fix this error, write `from` then the other module's name after the list of exports: ```javascript export {"React"} from "react"; ``` Alternatively, import the symbols separately with an `import` statement: ```javascript import {React} from "react"; export {React}; ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0154.md # E0154: unexpected expression; missing key for object entry ```config-for-examples { "globals": { "db": true } } ``` Object literals can contain methods, object spreads, shorthand properties, and key-value pairs. It is a syntax error to write a complex value (expression) without a key in an object literal: ```javascript async function loadUser(id) { let row = await db.selectOne('user', {id}); return { ...row, password: null, row.firstName + " " + row.lastName, }; } ``` To fix this error, write a key before the value: ```javascript async function loadUser(id) { let row = await db.selectOne('user', {id}); return { ...row, password: null, fullName: row.firstName + " " + row.lastName, }; } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0155.md # E0155: cannot reference private variables without object; use 'this.' ```config-for-examples { "globals": { "hashPassword": true } } ``` Classes can contain private properties. Their names start with `#`. It is a syntax error to use a private property without an object: ```javascript class Account { #email; #passwordHash; changePassword(newPassword) { #passwordHash = hashPassword(newPassword); } async save(db) { await db.saveAccount({ email: #email, passwordHash: #passwordHash, }); } } ``` To fix this error, write `this.` before the use of the private property: ```javascript class Account { #email; #passwordHash; changePassword(newPassword) { this.#passwordHash = hashPassword(newPassword); } async save(db) { await db.saveAccount({ email: this.#email, passwordHash: this.#passwordHash, }); } } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0156.md # E0156: private properties are not allowed in object literals ```config-for-examples { "globals": { "hashPassword": true } } ``` Classes can declare private properties with `#`. `Object` cannot have private properties. It is a syntax error to declare a private property in an object literal: ```javascript class Account { #email; #password; async save(db) { await db.saveAccount({ #email, #passwordHash: hashPassword(this.#password), }); } } class DataSmuggler { #contraband; setContraband(object, contraband) { return { ...object, #contraband: contraband, }; } getContraband(object) { return object.#contraband; } } ``` To fix this error, rename the properties to exclude the `#`: ```javascript class Account { #email; #password; async save(db) { await db.saveAccount({ email: this.#email, passwordHash: hashPassword(this.#password), }); } } ``` Alternatively, use a `Symbol` to attach private data to an object: ```javascript const Contraband = Symbol('contraband'); class DataSmuggler { setContraband(object, contraband) { return { ...object, [Contraband]: contraband, }; } getContraband(object) { return object[Contraband]; } } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0157.md # E0157: missing end of array; expected ']' An array literal requires a list of items surrounded by `[` and `]`. It is a syntax error to start an array literal with `[` but omit the final `]`: ```javascript let friends = ["Alice"; ``` To fix this error, write `]` at the end of the array literal: ```javascript let friends = ["Alice"]; ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0158.md # E0158: unexpected '=>'; expected parameter for arrow function, but got a literal instead ```config-for-examples { "globals": { "userID": true, "groupID": true } } ``` An arrow function has a parameter list followed by `=>` followed by a body. It is a syntax error to write an arrow function with a literal instead of a parameter list: ```javascript let fs = require("fs"); let path = process.argv[2]; fs.readFile(path, "utf-8" => { }); const queryUser = userID, groupID = 0 => { /* ... */ }; ``` To fix this error, write a parameter list before `=>`: ```javascript let fs = require("fs"); let path = process.argv[2]; fs.readFile(path, "utf-8", (err, data) => { }); ``` Alternatively, write `(` `)` around the parameter list: ```javascript const queryUser = (userID, groupID = 0) => { /* ... */ }; ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0159.md # E0159: unexpected literal in parameter list; expected parameter name A function parameter can be a variable name, an array destructuring, or an object destructuring. It is a syntax error for a function parameter list to contain a number literal: ```javascript function drop(array, count, 0) { return array.slice(count); } ``` To fix this error, make the literal a default value of a parameter: ```javascript function drop(array, count = 0) { return array.slice(count); } ``` See also: E0151 Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0160.md # E0160: unexpected '=>'; expected parameter for arrow function, but got an expression instead The left-hand side of `=>` must be a list of parameters. It is a syntax error if the left-hand side is instead an expression (such as a property access or a function call): ```javascript if (this.mapSize => this.capacity) { throw new Error("too many items"); } let fs = require("fs"); let path = process.argv[2]; fs.mkdir(path () => console.log("done")); ``` To fix this error, replace `=>` with the intended operator, such as `>=`: ```javascript if (this.mapSize >= this.capacity) { throw new Error("too many items"); } ``` Alternatively, make the left-hand side of `=>` valid by adding an operator (usually `,`) before the parameter list: ```javascript let fs = require("fs"); let path = process.argv[2]; fs.mkdir(path, () => console.log("done")); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0161.md # E0161: unclosed object literal; expected '}' ```config-for-examples { "globals": { "axios": true, "url": true } } ``` An object literal requires a list of properties surrounded by `{` and `}`. It is a syntax error to start an object literal with `{` but omit the final `}`: ```javascript let response = await axios.get(url.toString(), { validateStatus(_status) { return true; }, responseType: "stream" ); ``` To fix this error, write `}` at the end of the object literal: ```javascript let response = await axios.get(url.toString(), { validateStatus(_status) { return true; }, responseType: "stream" }); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0162.md # E0162: 'await' is only allowed in async functions ```config-for-examples { "globals": { "CONFIG_FILE": true, "fs": true, "parseConfig": true, "reallyTakeOverTheWorld": true } } ``` The `await` operator can be used in `async` functions and in modules at the top level. It is a syntax error to use the `await` operator in a non-`async` function: ```javascript function readConfig(configFilePath) { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } async function takeOverTheWorld() { let config = readConfig(CONFIG_FILE); if (config.prettyPlease) { await reallyTakeOverTheWorld(); } } ``` To fix this error, declare the function as `async`, ensuring that callers use `await` too: ```javascript async function readConfig(configFilePath) { let data = await fs.promises.readFile( configFilePath, "utf-8", ); return parseConfig(data); } async function takeOverTheWorld() { let config = await readConfig(CONFIG_FILE); if (config.prettyPlease) { await reallyTakeOverTheWorld(); } } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0163.md # E0163: newline is not allowed between 'async' and arrow function parameter list ```config-for-examples { "globals": { "app": true, "doHomePage": true } } ``` An `async` arrow function has a parameter list following the `async` keyword. It is a syntax error for the parameter list to start on line different from the `async` keyword: ```javascript app.get( "/", async (req, res) => { await doHomePage(req, res); }, ); ``` To fix this error, write `async` on the same line as the parameter list by removing the newline after `async`: ```javascript app.get( "/", async (req, res) => { await doHomePage(req, res); }, ); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0164.md # E0164: JSON syntax error [quick-lint-js configuration files][] (named `quick-lint-js.config`) contain valid JSON (according to [RFC8259][]). quick-lint-js cannot read a configuration file with malformed JSON: ```quick-lint-js.config { "globals": { // Google Analytics "ga": true, "google": true, } } ``` Common mistakes in JSON are trailing commas (disallowed) and comments (disallowed). To fix this error, correct mistakes in the JSON syntax for your configuration file: ```quick-lint-js.config { "globals": { " // Google Analytics": false, "ga": true, "google": true } } ``` [RFC8259]: https://datatracker.ietf.org/doc/html/rfc8259 [quick-lint-js configuration files]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0165.md # E0165: TypeScript style const field `const` fields are only allowed in TypeScript, not JavaScript ```javascript class C { const f = null; } ``` To fix this error, remove the `const` declarator from the field ```javascript class C { f = null; } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0166.md # E0166: "globals" descriptor "shadowable" property must be a boolean In a [quick-lint-js configuration file][], a entry in `"globals"` can have a descriptor object. A descriptor's `"shadowable"` property must be either `true`, `false`, or omitted. ```quick-lint-js.config { "globals": { "gsap": { "shadowable": 0 } } } ``` To fix this error, make the `"shadowable"` property `true` or `false`: ```quick-lint-js.config { "globals": { "gsap": { "shadowable": false } } } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0167.md # E0167: "globals" descriptor "writable" property must be a boolean In a [quick-lint-js configuration file][], a entry in `"globals"` can have a descriptor object. A descriptor's `"writable"` property must be either `true`, `false`, or omitted. ```quick-lint-js.config { "globals": { "gsap": { "writable": 0 } } } ``` To fix this error, make the `"writable"` property `true` or `false`: ```quick-lint-js.config { "globals": { "gsap": { "writable": false } } } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0168.md # E0168: "globals" must be an object In a [quick-lint-js configuration file][], `"globals"` must be an object or omitted. It is an error if `"globals"` is an array, a boolean, a number, a string, or `null`: ```quick-lint-js.config { "globals": [ "ga", "google", "$" ] } ``` To fix this error, make `"globals"` an object: ```quick-lint-js.config { "globals": { "ga": true, "google": true, "$": true } } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0169.md # E0169: "global-groups" must be a boolean or an array In a [quick-lint-js configuration file][], `"global-groups"` must be an array of strings, a boolean, or omitted. It is an error if `"global-groups"` is a boolean, a number, an object, a string, or `null`: ```quick-lint-js.config { "global-groups": { "ecmascript": true, "browser": true } } ``` To fix this error, make `"global-groups"` an array: ```quick-lint-js.config { "global-groups": [ "ecmascript", "browser" ] } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0170.md # E0170: "global-groups" entries must be strings In a [quick-lint-js configuration file][], items in the `"global-groups"` array must be strings. It is an error if an item is an array, a boolean, a number, an object, or `null`: ```quick-lint-js.config { "global-groups": [ "ecmascript", 2020, "browser" ] } ``` To fix this error, remove non-string items in `"global-groups"`: ```quick-lint-js.config { "global-groups": [ "ecmascript", "browser" ] } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0171.md # E0171: "globals" descriptor must be a boolean or an object In a [quick-lint-js configuration file][], each entry in `"globals"` must be a boolean or a descriptor object. It is an error if a `"globals"` item is an array, a number, a string, or `null`: ```quick-lint-js.config { "globals": { "gsap": "true" } } ``` To fix this error, make the `"globals"` entry `true` or `false`: ```quick-lint-js.config { "globals": { "gsap": true } } ``` [quick-lint-js configuration file]: https://quick-lint-js.com/config/ Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0172.md # E0172: missing body for function ```config-for-examples { "globals": { "numbers": true, "n": true } } ``` Functions declared with `function` require a body, which must `{` `}` surrounding a list of statements. It is a syntax error to omit the body of a function: ```javascript function isEven(n) return n % 2 === 0; for (let n of numbers) { if (isEven(n)) console.log(n); } ``` To fix this error, write `{` after the parameter list and `}` at the end of the function's body: ```javascript function isEven(n) { return n % 2 === 0; } for (let n of numbers) { if (isEven(n)) console.log(n); } ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0173.md # E0173: cannot assign to loop variable in for of/in loop ```config-for-examples { "globals": { "item": true } } ``` There are three kinds of `for` loops: C-style `for` loops (`;`), `for`-`in` loops, and `for`-`of` loops. It is a syntax error to write a `for`-`in` or `for`-`of` loop which declares a variable with `const` or `let` and initializes the variable: ```javascript function firstItem(collection) { for (const item = null of collection) { break; } return item; } ``` To fix this error, declare the variable outside the `for`-`in` or `for`-`of` loop with `let`: ```javascript function firstItem(collection) { let item = null; for (item of collection) { break; } return item; } ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0174.md # E0174: functions/methods should not have '=>' ```config-for-examples { "globals": { "axios": true, "url": true } } ``` Classes and object literals can contain methods. It is a syntax error to write `=>` before the method's body: ```javascript class Dog { bark() => { console.log("woof"); } } class Downloader { okStatuses = [200]; async download(url) { return await axios.get(url, { responseType: "json", validateStatus(status) => { return this.okStatuses.includes(status); }, }); } } ``` To fix this error, remove the `=>` to create a valid method: ```javascript class Dog { bark() { console.log("woof"); } } ``` Alternatively, in an object literal, create an arrow function instead of a method by adding `:` after the method name: ```javascript class Downloader { okStatuses = [200]; async download(url) { return await axios.get(url, { responseType: "json", validateStatus: (status) => { return this.okStatuses.includes(status); }, }); } } ``` Introduced in quick-lint-js version 0.5.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0175.md # E0175: expected variable name for 'import'-'as' ```config-for-examples { "globals": { "CE": true } } ``` `import` statements load things from other files. When importing, you can pick a different name for the imported data using the `as` keyword: It is a syntax error to write anything except a variable name after `as`: ```javascript import {createElement as "CE"} from "react"; function Hello() { return CE('h1', null, 'Hello, world!'); } import {first as "first-element"} from "./utilitylib.mjs"; ``` To fix this error, write a variable name after `as`: ```javascript import {createElement as CE} from "react"; function Hello() { return CE('h1', null, 'Hello, world!'); } ``` Alternatively, swap the left and right side of `as`: ```javascript import {"first-element" as first} from "./utilitylib.mjs"; ``` Introduced in quick-lint-js version 0.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0176.md # E0176: missing arrow operator for arrow function Arrow functions have a parameter list followed by `=>` followed by a function body. It is a syntax error to omit the `=>`: ```javascript let fs = require("fs"); fs.readFile(process.argv[2], (err, data) { console.log(data); }); ``` To fix this error, write `=>` after the parameter list: ```javascript let fs = require("fs"); fs.readFile(process.argv[2], (err, data) => { console.log(data); }); ``` Alternatively, write `function` before the parameter list: ```javascript let fs = require("fs"); fs.readFile(process.argv[2], function(err, data) { console.log(data); }); ``` Introduced in quick-lint-js version 0.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0177.md # E0177: React/JSX is not allowed in vanilla JavaScript code ```config-for-examples { "globals": { "React": true, "ReactDOM": true } } ``` Vanilla JavaScript does not support JSX syntax (used in React code). It is a syntax error to create a JSX element or JSX fragment in vanilla JavaScript: ```javascript ReactDOM.render(

Hello, world!

, document.getElementById('root') ); ``` To fix this error, use `React.createElement` instead of JSX syntax: ```javascript ReactDOM.render( React.createElement('h1', null, 'Hello, world!'), document.getElementById('root') ); ``` Alternatively, use [`--language=javascript-jsx`][cli-language] instead of `--language=javascript`. [cli-language]: ../../cli/#language Introduced in quick-lint-js version 0.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0178.md # E0178: 'await' cannot be followed by an arrow function; use 'async' instead ```config-for-examples { "globals": { "app": true, "doHomePage": true } } ``` Arrow functions can contain `await` if they are marked `async`. It is an error to write `await` instead of `async` when making an arrow function: ```javascript app.get("/", await (req, res) => { await doHomePage(req, res); }); ``` To fix this error, write `async` instead of `await`: ```javascript app.get("/", async (req, res) => { await doHomePage(req, res); }); ``` Introduced in quick-lint-js version 0.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0179.md # E0179: return statement returns nothing (undefined) A `return` statement can have an optional expression. If the expression is omitted, `undefined` is returned. If a `return` statement has an expression, the expression must start on the same line as the `return` keyword. If an expression starts on the next line, the `return` statement behaves as if no expression was given, so the returned value is `undefined` and the next line is skipped: ```javascript function getWebsiteBaseURL() { return 'https://quick-lint-js.com/'; } // TypeError: URL constructor: undefined is not a valid URL. console.log(getWebsiteBaseURL().hostname); ``` To fix this error, put the returned value on the same line as the `return` keyword: ```javascript function getWebsiteBaseURL() { return 'https://quick-lint-js.com/'; } // "quick-lint-js.com" console.log(getWebsiteBaseURL().hostname); ``` Introduced in quick-lint-js version 0.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0180.md # E0180: stray comma in function parameter ```config-for-examples { "globals": { "data": true } } ``` A function parameter can be a variable name, an array destructuring, or an object destructuring. It is a syntax error for a parameter name to be in parentheses with a comma: ```javascript-ignoring-extra-errors let firsts = data.map([(x,)] => x); ``` To fix this error, remove the comma: ```javascript let firsts = data.map([x] => x); ``` Introduced in quick-lint-js version 1.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0181.md # E0181: unclosed string literal JSX attribute values can be strings. These strings need to be closed with either `"` or `'` (whichever was used to start the string). It is a syntax error to omit `"` or `'`: ```javascript-ignoring-extra-errors function NavLink({href, children}) { return
  • {children}
  • ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0182.md # E0182: '>' is not allowed directly in JSX text; write {'>'} or &gt; instead In the children of a JSX element, you can write arbitrary text. However, it is a syntax error to write `>` unescaped in JSX text: ```javascript-jsx function Breadcrumbs({page, subpage}) { return <> {page.name} > {subpage.name} ; } ``` To fix this error, write `{'>'}` or `>` instead: ```javascript-jsx function Breadcrumbs({page, subpage}) { return <> {page.name} > {subpage.name} ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0183.md # E0183: '}' is not allowed directly in JSX text; write {'}'} instead In the children of a JSX element, you can write arbitrary text. However, it is a syntax error to write `}` unescaped in JSX text: ```javascript-jsx function ClosingBrackets() { return
    • )
    • ]
    • }
    ; } ``` To fix this error, write `{'}'}` instead: ```javascript-jsx function ClosingBrackets() { return
    • )
    • ]
    • {"}"}
    ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0184.md # E0184: missing 'if' after 'else' In an `if`-`else if`-`else` chain, it is a syntax error to omit the `if` keyword after `else`: ```javascript function lastName(name) { let parts = name.split(); if (parts.length === 2) { return parts[1]; } else (parts.length === 1) { return name; } else { throw new Error(`unexpected name: ${name}`); } } ``` To fix this error, write `if` between `else` and the condition: ```javascript function lastName(name) { let parts = name.split(); if (parts.length === 2) { return parts[1]; } else if (parts.length === 1) { return name; } else { throw new Error(`unexpected name: ${name}`); } } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0185.md # E0185: assignment to imported variable; imported variable declared here It is a `ReferenceError` to assign to variables imported from another module: ```javascript import { config } from "./default-config.js"; function updateConfig(newConfig) { config = newConfig; } function dumpConfig() { console.log(config); } ``` To fix this error, create a new variable with `let` and use it instead. ```javascript import { config as defaultConfig } from "./default-config.js"; let config = defaultConfig; function updateConfig(newConfig) { config = newConfig; } function dumpConfig() { console.log(config); } ``` See also: E0003 Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0186.md # E0186: missing '...' in JSX attribute spread In a JSX tag, you can use an object as a source of attributes. It is a syntax error to omit the `...` before the object: ```javascript-jsx function Link({text, ...props}) { return {text}; } ``` To fix this error, write `...` after `{` in the spread attribute: ```javascript-jsx function Link({text, ...props}) { return {text}; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0187.md # E0187: mismatched JSX tags; expected </foo> ```config-for-examples { "globals": { "Link": true } } ``` In JSX, each opening tag must either be self-closing or have a corresponding closing tag. It is a syntax error for the closing tag to have a different tag name than the opening tag: ```javascript-jsx function Section({children}) { return
    {children}
    ; } function SignUpButton() { return
    Join now
    ; } ``` To fix this error, make the ending tag and the opening tag use the same name: ```javascript-jsx function Section({children}) { return
    {children}
    ; } ``` Alternatively, swap the incorrectly-nested closing tags: ```javascript-jsx function SignUpButton() { return
    Join now
    ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0188.md # E0188: '=' changes variables; to compare, use '===' instead ```config-for-examples { "globals": { "xs": true, "out": true } } ``` In an `if` statement or a loop, it is likely a mistake to use `=` to compare a variable with a constant: ```javascript let headingLinks = []; for (let el of document.querySelectorAll("a")) { if (el.parentNode.tag = "H1") { headingLinks.push(el); } } for (let x, i = 0; x = null; ++i) { if (xs[i] < 0) { break; } else if (xs[i] > 0) { x = xs[i]; } out.push(x); } ``` To fix this error, write `===` or `==` instead of `=` to compare for equality: ```javascript let headingLinks = []; for (let el of document.querySelectorAll("a")) { if (el.parentNode.tag === "H1") { headingLinks.push(el); } } ``` Alternatively, if assignment was intended, write parentheses around the assignment to suppress the warning: ```javascript for (let x, i = 0; (x = null); ++i) { if (xs[i] < 0) { break; } else if (xs[i] > 0) { x = xs[i]; } out.push(x); } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0189.md # E0189: missing '<>' and '</>' to enclose multiple children To return multiple JSX elements from a component, you must return a fragment. It is a syntax error to return multiple elements without a fragment: ```javascript-jsx function TodoEntry({title, children}) { return (

    {title}

    {children}
    ); } ``` To fix this error, wrap the elements in a fragment using `<>` and ``: ```javascript-jsx function TodoEntry({title, children}) { return <>

    {title}

    {children}
    ; } ``` Alternatively, wrap the elements in another element: ```javascript-jsx function TodoEntry({title, children}) { return

    {title}

    {children}
    ; } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0190.md # E0190: missing comparison; '===' does not extend to the right side of '||' In English, we might say “if the selection is ‘agree’ or ‘strongly agree’, return a rating of 1”. If this English phrase is translated naïvely into JavaScript, the code will behave as if every selection has a rating of 1: ```javascript function getRating(radioElement) { let selection = radioElement.value; if (selection === "agree" || "strongly agree") { return 1; } else if (selection === "disagree") { return 0; } else if (selection === "strongly disagree") { return -1; } } ``` This happens because `if (selection === "agree" || "strongly agree")` is interpreted as `if ((selection === "agree") || "strongly agree")`, i.e. “if selection is ‘agree’, or if ‘strongly agree’ is truthy, then …”. Because the string `"strongly agree"` is not empty, it is truthy, and the condition is always true. To fix this error, write the `==` or `===` comparison on both sides of `||`: ```javascript function getRating(radioElement) { let selection = radioElement.value; if (selection === "agree" || selection === "strongly agree") { return 1; } else if (selection === "disagree") { return 0; } else if (selection === "strongly disagree") { return -1; } } ``` Note: As of quick-lint-js version 2.11.0, this diagnostic treats `undefined` as a constant. If you declare your own variable named `undefined`, `E0190` might be incorrectly reported. To work around this issue, rename your variable to something other than `undefined`, such as `isUndefined`. Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0191.md # E0191: event attributes must be camelCase In HTML, attributes are case-insensitive; `onclick` is the same as `onClick` and `ONCLICK`. In React, attributes are case-sensitive. It is a mistake for an event attribute (starting with `on`) to be all lower-case: ```javascript-jsx import React from "react"; function TodoEntry({addTodo, changePendingTodo}) { return
    ; } ``` To fix this error, fix the capitalization by writing the attribute in lowerCamelCase: ```javascript-jsx import React from "react"; function TodoEntry({addTodo, changePendingTodo}) { return
    ; } ``` This diagnostic enabled in the `"react"` [JSX mode][]. Introduced in quick-lint-js version 2.0.0. [JSX Mode]: https://quick-lint-js.com/errors/jsx/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0192.md # E0192: attribute has wrong capitalization In HTML, attributes are case-insensitive; `colspan` is the same as `colSpan` and `COLSPAN`. In React, attributes are case-sensitive. It is a mistake for an attribute for a built-in element to have the wrong capitalization: ```javascript-jsx import React from "react"; function Header({columns}) { return Name {columns.map(column => {column})} ; } ``` To fix this error, fix the capitalization of the attribute: ```javascript-jsx import React from "react"; function Header({columns}) { return Name {columns.map(column => {column})} ; } ``` This diagnostic enabled in the `"react"` [JSX mode][]. Introduced in quick-lint-js version 2.0.0. [JSX Mode]: https://quick-lint-js.com/errors/jsx/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0193.md # E0193: misspelled React attribute; write 'className' instead React has a different name for some attributes than HTML. It is a mistake to write the HTML attribute instead of the React attribute: ```javascript-jsx import React from "react"; function Title({page}) { return

    {page.name}

    ; } ``` To fix this error, write the name of the attribute understood by React: ```javascript-jsx import React from "react"; function Title({page}) { return

    {page.name}

    ; } ``` This diagnostic enabled in the `"react"` [JSX mode][]. Introduced in quick-lint-js version 2.0.0. [JSX Mode]: https://quick-lint-js.com/errors/jsx/ --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0194.md # E0194: missing parentheses around left-hand side of `**`; `**` operator cannot be used after unary `-` without parentheses JavaScript does not allow unary operators left of a `**` expression. It is a syntax error to write unary `-`, `+`, `!`, or `~` before a `**` expression: ```javascript function parity(n) { return -1 ** n; } function notbit(bit) { return ~2**bit } ``` To fix this error, write parentheses around the left-hand side of the `**` expression: ```javascript function parity(n) { return (-1) ** n; } ``` Alternatively, write parentheses around the `**` expression: ```javascript function notbit(bit) { return ~(2**bit) } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0195.md # E0195: missing parentheses around operand of `typeof`; `typeof` operator cannot be used before `**` without parentheses ```config-for-examples { "globals": { "assert": true } } ``` JavaScript does not allow unary operators left of a `**` expression. It is a syntax error to write `delete`, `typeof`, or `void` before a `**` expression: ```javascript assert(typeof 10 ** 7 === "number"); ``` To fix this error, write parentheses around the `**` expression: ```javascript assert(typeof (10 ** 7) === "number"); ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0196.md # E0196: new variable shadows existing variable ```config-for-examples { "globals": { "fs": true, "inputPath": true, "path": true } } ``` In JavaScript, `const` and `let` create new variables. They do not modify existing variables. It is likely a mistake if a new variable is created with the same name as an existing variable: ```javascript let stream; if (typeof path !== 'undefined') { let stream = fs.createWriteStream(path); } else { let stream = fs.createWriteStream("data.txt"); } const p = inputPath.replace("\\", "/"); const dirPath = path.dirname(p); while (!fs.isWritable(p)) { const p = dirPath + "/"; } ``` To fix this error, remove the 'let' or 'const' keyword to turn the declaration into an assignment: ```javascript let stream; if (typeof path !== 'undefined') { stream = fs.createWriteStream(path); } else { stream = fs.createWriteStream("data.txt"); } ``` Alternatively, use the variable after declaring it: ```javascript const p = inputPath.replace("\\", "/"); const dirPath = path.dirname(p); while (!fs.isWritable(p)) { const p = dirPath + "/"; fs.remove(p); fs.createDirectory(p); } ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0197.md # E0197: '“' is not allowed for strings; use " instead JavaScript string literals start with either `"` or `'` (straight quotes). It is a syntax error to use smart quotes instead of straight quotes to write a string literal: ```javascript let name = “Alice”; console.log(‘hello, ’ + name); ``` To fix this error, replace `‘` and `’` with `'`, and replace `“` and `”` with `"`: ```javascript let name = "Alice"; console.log('hello, ' + name); ``` Introduced in quick-lint-js version 2.0.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0198.md # E0198: unexpected statement before first switch case, expected 'case' or 'default' ```config-for-examples { "globals": { "isEven": true, "n": true } } ``` `switch` statements contain zero or more labelled statements. It is a syntax error to write a statement inside a `switch`'s body before the first label: ```javascript function colorToHexCode(color) { switch (color) { throw new Error(`unknown color ${color}`); case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } switch (isEven(n)) { console.log(`${n} is even`); } ``` To fix this error, write a `default` or `case` label at the beginning of the `switch`: ```javascript function colorToHexCode(color) { switch (color) { default: throw new Error(`unknown color ${color}`); case 'red': return '#ff0000'; case 'green': return '#00ff00'; case 'blue': return '#0000ff'; } } ``` Alternatively, replace `switch` with `if`: ```javascript if (isEven(n)) { console.log(`${n} is even`); } ``` Introduced in quick-lint-js version 2.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0199.md # E0199: unclosed class; expected '}' by end of file Every `{` introducing a class block must have a matching `}` ending a class block. It is a syntax error to omit the `}`: ```javascript class Banana { peel() { throw new Error("Bananas can't peel themselves!"); } ``` To fix this error, write a matching `}`: ```javascript class Banana { peel() { throw new Error("Bananas can't peel themselves!"); } } ``` Introduced in quick-lint-js version 2.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0200.md # E0200: break can only be used inside of a loop or switch ```config-for-examples { "globals": { "hand": true, "friends": true } } ``` A `break` statement exits a `do`-`while` loop, `for` loop, `while` loop, or `switch` statement. It is a syntax error for a `break` statement to appear outside these loops or a `switch` statement: ```javascript friends.forEach((friend) => { hand.giveHighFive(friend); if (hand.isTired) { break; } }); ``` To fix this error, write a `for`-`of` loop instead of using the `forEach` method: ```javascript for (const friend of friends) { hand.giveHighFive(friend); if (hand.isTired) { break; } } ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0201.md # E0201: continue can only be used inside of a loop ```config-for-examples { "globals": { "benchmarks": true } } ``` A `continue` statement exit the current iteration of a `do`-`while` loop, `for` loop, or `while` loop. It is a syntax error for a `continue` statement to appear outside these loops: ```javascript benchmarks.forEach(benchmark => { if (benchmark.shouldSkip) continue; benchmark.warmUp(); if (benchmark.varianceTooHigh) continue; benchmark.run(); }); ``` To fix this error, write a `for`-`of` loop instead of using the `forEach` method: ```javascript for (let benchmark of benchmarks) { if (benchmark.shouldSkip) continue; benchmark.warmUp(); if (benchmark.varianceTooHigh) continue; benchmark.run(); } ``` Alternatively, use `return` to exit the current iteration's function: ```javascript benchmarks.forEach(benchmark => { if (benchmark.shouldSkip) return; benchmark.warmUp(); if (benchmark.varianceTooHigh) return; benchmark.run(); }); ``` Alternatively, write an `if` statement to skip the undesired code: ```javascript benchmarks.forEach(benchmark => { if (!benchmark.shouldSkip) { benchmark.warmUp(); if (!benchmark.varianceTooHigh) { benchmark.run(); } } }); ``` Introduced in quick-lint-js version 0.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0202.md # E0202: missing '=' after variable The following code has a missing equal '=' after variable name. ```javascript let x new Array(); ``` To fix this error, add '=' after variable `x`. ```javascript let x = new Array(); ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0203.md # E0203: depth limit exceeded JavaScript code can contain nested functions, arrays, objects, classes, etc. quick-lint-js only supports nesting up to a limit. Most code shouldn't hit this limit. If you do hit this limit, refactor your code to reduce nesting. Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0204.md # E0204: error generator function star belongs after keyword function The following code has misplaced '*'. ```javascript let x = *function(y) { yield y; }; ``` To fix this error, move the '*' after the keyword function. ```javascript let x = function*(y) { yield y; }; ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0205.md # E0205: error missing initializer in const declaration The following code is missing initialization for const variable declaration. ```javascript const x; ``` To fix this error, initialize the variable x with some value. ```javascript const x = 10; ``` Another way to fix this error, change const to let. ```javascript let x; ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0206.md # E0206: label named 'await' not allowed in async function The following code is using label named 'await' in an async function. ```javascript async function f() { await: } ``` To fix this error, rename label await to something else. ```javascript async function f() { label: } ``` Another way to fix this error, make 'f' a normal function rather than an async function. ```javascript function f() { await: } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0207.md # E0207: code point in Unicode escape sequence must not be greater than U+10FFFF Identifiers, string literals, and template literals can contain Unicode escape sequences starting with `\u`. It is a syntax error for a Unicode escape sequence to refer to a character which is beyond the range of valid Unicode code points (U+0000 to U+10FFFF): ```javascript class ChirpSound {} let bird\u{360000} = new ChirpSound(); let x = "hello\u{abcdef}"; ``` To fix this error, make sure that the escaped code point is between U+0000 and U+10FFFF inclusive. ```javascript class ChirpSound {} let bird\u{3600} = new ChirpSound(); let x = "hello\u{abcde}"; ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0208.md # E0208: cannot access private identifier outside class The following code is accessing a private identifier outside the class. ```javascript class C { #x = 10; } function f(c) { c.#x = 20; } ``` To fix this error, move function `f` as a static member of class `C` . ```javascript class C { #x = 10; static f(c) { c.#x = 20; } } ``` Another way to fix this error, remove `#` before variable `x`. ```javascript class C { x = 10; } function f(c) { c.x = 20; } ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0209.md # E0209: commas are not allowed between class methods Classes and object literals have a similar syntax for declaring methods. Object literal entries are separated by commas, but class entries are not separated by commas. It is a syntax error to use a comma to separate class entries: ```javascript class Doggie { speak() { console.log('woof!'); }, eat() { this.hungry = false; }, } ``` To fix this error, remove the `,`s: ```javascript class Doggie { speak() { console.log('woof!'); } eat() { this.hungry = false; } } ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0210.md # E0210: unopened block comment ```config-for-examples { "globals": { "heightInCM": true, "debugPrint": true, "state": true } } ``` Block comments start with `/*` and end with `*/`. It is a syntax error for a block comment to end but not start: ```javascript-ignoring-extra-errors // // this code is really complicated. // some might say too complicated. */ function yes() { return true; } /* console.log("[debug] state:"); debugPrint(state, /*depth=*/3); */ let heightInFeet = heightInCM */ 3.28; ``` To fix this error, remove the `*/`: ```javascript // // this code is really complicated. // some might say too complicated. function yes() { return true; } ``` Alternatively, use `//` or `if (false)` to avoid nesting block comments: ```javascript if (false) { console.log("[debug] state:"); debugPrint(state, /*depth=*/3); } ``` Alternatively, write an expression between `*` and `/`: ```javascript let heightInFeet = heightInCM * 100 / 3.28; ``` Introduced in quick-lint-js version 0.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0211.md # E0211: missing parentheses around self-invoked function Invoking an arrow function immediately without parentheses is a syntax error. For example: ``` () => { console.log('hi'); }() ``` To fix this error, add parentheses around the entire function definition, before the invocation: ``` (() => { console.log('hi'); })() ``` Introduced in quick-lint-js version 2.4.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0212.md # E0212: integer cannot be represented and will be rounded JavaScript stores integers as 64-bit floating-point numbers. Integers outside this range will lose precision: ```javascript const kilo = 1_000; const mega = 1_000_000; const giga = 1_000_000_000; const tera = 1_000_000_000_000; const peta = 1_000_000_000_000_000; const exa = 1_000_000_000_000_000_000; const zetta = 1_000_000_000_000_000_000_000; // yotta is equal to 999999999999999983222784 const yotta = 1_000_000_000_000_000_000_000_000; ``` To fix this error, use a BigInt instead of a Number: ```javascript const kilo = 1_000n; const mega = 1_000_000n; const giga = 1_000_000_000n; const tera = 1_000_000_000_000n; const peta = 1_000_000_000_000_000n; const exa = 1_000_000_000_000_000_000n const zetta = 1_000_000_000_000_000_000_000n; const yotta = 1_000_000_000_000_000_000_000_000n; ``` Introduced in quick-lint-js version 2.5.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0213.md # E0213: TypeScript's 'interface' feature is not allowed in JavaScript code JavaScript does not support interfaces. It is a syntax error to write a TypeScript interface in JavaScript code: ```javascript interface Response { ok: boolean; error?: string; data?: T; } ``` To fix this error, rename your file to have a `.ts` or `.tsx` suffix. Alternatively, use JSDoc to declare the interface: ```javascript /** * @typedef {Object} Response * @prop {boolean} ok * @prop {string} [error] * @prop {Object} data */ ``` Introduced in quick-lint-js version 2.5.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0214.md # E0214: use of undeclared type A TypeScript type annotation must refer to a class, enum, generic parameter, interface, or type alias. It is an error to a type which does not exist: ```typescript-jsx interface Response { ok: bool; error?: string; data?: object; } function padString( s: string, alignment: Alignment, ): string { /* ... */ } const Title: FC = () => { return

    Welcome!

    ; }; ``` To fix this error, fix the name of the referenced type: ```typescript interface Response { ok: boolean; error?: string; data?: object; } ``` Alternatively, declare the type: ```typescript enum Alignment { LEFT, RIGHT, CENTER }; function padString( s: string, alignment: Alignment, ): string { /* ... */ } ``` Alternatively, import the type: ```typescript-jsx import {type FC} from "react"; const Title: FC = () => { return

    Welcome!

    ; }; ``` Alternatively, if the type is global in your environment, [write a quick-lint-js.config file](https://quick-lint-js.com/config/). Introduced in quick-lint-js version 2.5.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0215.md # E0215: unclosed interface; expected '}' by end of file Every `{` introducing an interface block must have a matching `}` ending an interface block. It is a syntax error to omit the `}`: ```typescript export interface API { fetch(uri, params); ``` To fix this error, write a matching `}`: ```typescript export interface API { fetch(uri, params); } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0216.md # E0216: TypeScript interface properties cannot be 'static' TypeScript interfaces describe objects (instances), not classes. It is a syntax error to create a static (class) property in an interface: ```typescript interface Clock { static now(): number; }; class SlowClock implements Clock { static now(): number { return Date.now() / 10; } } ``` To fix this error, make the property non-static and apply the interface to the class itself (not on instances): ```typescript interface Clock { now(): number; }; const SlowClock: Clock = class SlowClock { static now(): number { return Date.now() / 10; } }; ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0217.md # E0217: TypeScript interface methods cannot be marked 'async' ```config-for-examples { "globals": { "LoadedData": true } } ``` The `async` keyword on methods changes the body of that method. TypeScript interface methods do not have bodies. Therefore, `async` does not make sense on TypeScript interface methods, and it is a syntax error to write it: ```typescript interface DataLoader { async load(): Promise; } ``` To fix this error, remove the `async` keyword: ```typescript interface DataLoader { load(): Promise; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0218.md # E0218: TypeScript interface methods cannot be marked as a generator ```config-for-examples { "globals": { "Generator": true } } ``` `*` on a method allows using the `yield` keyword in the body of the method. TypeScript interface methods do not have bodies. Therefore, `*` does not make sense on TypeScript interface methods, and it is a syntax error to write it: ```typescript interface RandomSource { *makeRandomNumbers(): Generator; } ``` To fix this error, remove the `*`: ```typescript interface RandomSource { makeRandomNumbers(): Generator; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0219.md # E0219: interface properties are always public and cannot be private TypeScript interfaces describe the properties of objects usable from outside that object's class. Therefore, all interface properties must be public. It is an error to declare a private property in an interface: ```typescript interface Painter { paintPixel(pos, color); #normalizeColor(color); private normalizePos(pos); } class CanvasPainter implements Painter { paintPixel(pos, color) { let c = this.#normalizeColor(color); let p = this.normalizePos(pos); // ... } #normalizeColor(color) { // ... } private normalizePos(pos) { // ... } } ``` To fix this error, remove the private property from the interface: ```typescript interface Painter { paintPixel(pos, color); } class CanvasPainter implements Painter { paintPixel(pos, color) { let c = this.#normalizeColor(color); let p = this.normalizePos(pos); // ... } #normalizeColor(color) { // ... } private normalizePos(pos) { // ... } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0220.md # E0220: TypeScript interface methods cannot contain a body TypeScript interfaces describe the properties of objects, but do not describe implementation of methods for those objects. It is a syntax error to write a method body in an interface: ```typescript interface Clock { setDate(y, m, d); setTime(h, m, s); setInstant(y, m, d, hour, min, sec) { this.setDate(y, m, d); this.setTime(hour, min, sec); } } class SystemClock implements Clock { setDate(y, m, d) { // ... } setTime(h, m, s) { // ... } } ``` To fix this error, convert the interface into an abstract base class: ```typescript abstract class Clock { abstract setDate(y, m, d); abstract setTime(h, m, s); setInstant(y, m, d, hour, min, sec) { this.setDate(y, m, d); this.setTime(hour, min, sec); } } class SystemClock extends Clock { setDate(y, m, d) { // ... } setTime(h, m, s) { // ... } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0221.md # E0221: TypeScript interface fields cannot be initalized TypeScript interfaces describe the properties of objects, but do not describe default values for those properties. It is a syntax error to initialize a property with `=` in an interface: ```typescript interface Entity { x: number = 0; y: number = 0; tick(): void; } class Player implements Entity { x: number; y: number; tick(): void { // ... } } ``` To fix this error, convert the interface into an abstract base class: ```typescript abstract class Entity { x: number = 0; y: number = 0; abstract tick(): void; } class Player extends Entity { tick(): void { // ... } } ``` Alternatively, remove the initializer from the interface, making sure to initialize in implementing classes: ```typescript interface Entity { x: number; y: number; tick(): void; } class Player implements Entity { x: number = 0; y: number = 0; tick(): void { // ... } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0222.md # E0222: 'private' is not allowed in JavaScript JavaScript private properties are declared using `#`. It is a syntax error to write `private` in JavaScript code: ```javascript class Downloader { private downloadCount = 0; download() { this.downloadImpl(); this.downloadCount += 1; } private downloadImpl() { // ... } } ``` To fix this error, rename the property with a `#` prefix and remove the `private` keyword: ```javascript class Downloader { #downloadCount = 0; download() { this.#downloadImpl(); this.#downloadCount += 1; } #downloadImpl() { // ... } } ``` Alternatively, make the property public by removing the `private` keyword: ```javascript class Downloader { downloadCount = 0; download() { this.downloadImpl(); this.downloadCount += 1; } downloadImpl() { // ... } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0223.md # E0223: missing semicolon after field Class fields and TypeScript interface fields must end with either a semicolon (`;`) or a newline. It is a syntax error to omit the semicolon and write something on the same line after the field: ```javascript class Potato { sprouts = [] age = 0 } ``` To fix this error, write `;` to separate the fields: ```javascript class Potato { sprouts = []; age = 0; } ``` Alternatively, put the fields on separate lines: ```javascript class Potato { sprouts = [] age = 0 } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0224.md # E0224: TypeScript type annotations are not allowed in JavaScript code JavaScript variables and function returns cannot be explicitly typed with an annotation: ```javascript async function fetchJSON(uri: string): Promise { let req: Response = await fetch(uri); return await req.json(); } ``` To fix this error, rename your file to have a `.ts` or `.tsx` suffix. Alternatively, use JSDoc to write the annotations: ```typescript /** * @param {string} uri * @returns {Promise} */ async function fetchJSON(uri) { /** @type {Response} */ let req = await fetch(uri); return await req.json(); } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0225.md # E0225: index signatures require a value type A TypeScript index signature has a key type and a value type. It is a syntax error to omit the value type: ```typescript interface StringArray { readonly [index: number]; } interface StringDictionary { [k: string]; } ``` To fix this error, write `:` then the type of the value: ```typescript interface StringArray { readonly [index: number]: string; } interface StringDictionary { [k: string]: any; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0226.md # E0226: missing semicolon after index signature TypeScript index signatures in interfaces must end with either a semicolon (`;`) or a newline. It is a syntax error to omit the semicolon and write something on the same line after the index signature: ```typescript interface APIData { [key: string]: number | string void; } ``` To fix this error, write a correct type for the index signature: ```typescript interface APIData { [key: string]: number | string | void; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0227.md # E0227: index signature must be a field, not a method A TypeScript index signature describes a property. TypeScript only supports the field syntax for index signatures. It is a syntax error to write an index signature using method syntax: ```typescript interface EventTable { [eventName: string](event: Event): void; } ``` To fix this error, write the value type using function type syntax instead: ```typescript interface EventTable { [eventName: string]: (event: Event) => void; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0228.md # E0228: TypeScript optional properties are not allowed in JavaScript code `?` on class properties is a TypeScript feature. It is a syntax error to write `?` on a property in JavaScript code: ```javascript class Entity { parent? = null; } ``` To fix this error, erase the `?`: ```javascript class Entity { parent = null; } ``` Alternatively, rename your file to have a `.ts` or `.tsx` suffix Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0229.md # E0229: missing name for class method JavaScript class methods must have a name. It is a syntax error to omit the name: ```javascript class KittyCat { () { console.log("meow"); } } new KittyCat().talk(); ``` To fix this error, write the method's name before the `(`: ```javascript class KittyCat { talk() { console.log("meow"); } } new KittyCat().talk(); ``` Alternatively, to really give the method an empty name, write the name as a string: ```javascript class KittyCat { ""() { console.log("meow"); } } new KittyCat()[""](); ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0230.md # E0230: TypeScript's 'readonly' feature is not allowed in JavaScript code `readonly` on class properties is a TypeScript feature. It is a syntax error to use `readonly` in JavaScript code: ```javascript class Fetcher { readonly baseURL; constructor(baseURL) { this.baseURL = baseURL; } } ``` To fix this error, erase the `readonly`: ```javascript class Fetcher { baseURL; constructor(baseURL) { this.baseURL = baseURL; } } ``` Alternatively, rename your file to have a `.ts` or `.tsx` suffix Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0231.md # E0231: methods cannot be readonly Class and interface methods cannot be marked as read-only. It is a syntax error to write `readonly` on a method: ```typescript class SecureFetcher { readonly fetch() { // ... } } // TypeScript only: interface Hasher { readonly mix(data: string): void; } ``` To fix this error, remove the `readonly` keyword: ```javascript class SecureFetcher { fetch() { // ... } } ``` Alternatively, for TypeScript interface methods, convert the method into a field with a function type: ```typescript interface Hasher { readonly mix: (data: string) => void; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0232.md # E0232: 'readonly static' is not allowed; write 'static readonly' instead The order of property specifiers like `readonly` and `static` matters. The correct order is: 1. `static` 2. `readonly` (TypeScript only) It is a syntax error to write specifiers in the wrong order: ```typescript class Logger { readonly static instance = new Logger(); } ``` To fix this error, rearrange the specifiers: ```typescript class Logger { static readonly instance = new Logger(); } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0233.md # E0233: TypeScript generics are not allowed in JavaScript code It is a syntax error to write TypeScript generic parameters or arguments in JavaScript code: ```javascript class HashSet { // ... } ``` To fix this error, rename your file to have a `.ts` or `.tsx` suffix. Alternatively, use JSDoc to write the generic parameters: ```javascript /** * @template Value */ class HashSet { // ... } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0234.md # E0234: 'protected' is not allowed in JavaScript JavaScript does not support protected properties. It is a syntax error to declare a class property as `protected`: ```javascript class ObjectPool { protected makeImpl() { return {}; } } class NodePool extends ObjectPool { protected makeImpl() { return new Node(null); } } ``` To fix this error, remove the `protected` keyword, and consider putting a `_` prefix in the property name to signal it should not be called outside the class: ```javascript class ObjectPool { _makeImpl() { return {}; } } class NodePool extends ObjectPool { _makeImpl() { return new Node(null); } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0235.md # E0235: missing quotes around module name Module names are strings. It is a syntax error to import a module without enclosing the module name in quotation marks: ```javascript import React from react; import { readFile } from fs; ``` To fix this error, add quotation marks around the module's name: ```javascript import React from "react"; import { readFile } from 'fs'; ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0236.md # E0236: assignment-asserted field must have a type annotation ```config-for-examples { "globals": { "Address": true } } ``` In TypeScript, `!` after a field name indicates a *definite assignment assertion*. Definite-assignment-asserted fields must have a type annotation. It is a syntax error to write `!` on a field without any type annotation: ```typescript class AccountBuilder { name!; address!; setName(value: string) { this.name = value; return this; } setAddress(value: Address) { this.address = value; return this; } } ``` To fix this error, write a type annotation: ```typescript class AccountBuilder { name!: string; address!: Address; setName(value: string) { this.name = value; return this; } setAddress(value: Address) { this.address = value; return this; } } ``` Alternatively, remove the `!`: ```typescript class AccountBuilder { name; address; setName(value: string) { this.name = value; return this; } setAddress(value: Address) { this.address = value; return this; } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0237.md # E0237: interface properties cannot be marked public explicitly In TypeScript interfaces, all properties are public. It is a syntax error to explicitly write the `public` keyword on an interface property: ```typescript interface Painter { public paintPixel(pos, color); } class CanvasPainter implements Painter { public paintPixel(pos, color) { // ... } } ``` To fix this error, remove the `public` keyword from the interface property: ```typescript interface Painter { paintPixel(pos, color); } class CanvasPainter implements Painter { public paintPixel(pos, color) { // ... } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0238.md # E0238: assignment-asserted fields are not supported in interfaces In TypeScript, `!` after a field name indicates a *definite assignment assertion*. These assertions only make sense for classes, not for interfaces. It is a syntax error to write a definite assignment assertion on an interface field: ```typescript interface Point2D { x!: number; y!: number; } ``` To fix this error, remove the `!`: ```typescript interface Point2D { x: number; y: number; } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0239.md # E0239: TypeScript assignment-asserted fields are not supported in JavaScript In TypeScript, `!` after a class field name indicates a *definite assignment assertion*. It is a syntax error to use a definite assignment assertion on a class field in JavaScript code: ```javascript class AccountBuilder { name!: string; address = null; setName(value) { this.name = value; return this; } setAddress(value) { this.address = value; return this; } } ``` To fix this error, remove the `!` after the field name, and remove the field's type: ```javascript class AccountBuilder { name; address = null; setName(value) { this.name = value; return this; } setAddress(value) { this.address = value; return this; } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0240.md # E0240: '!' is not allowed on methods ```config-for-examples { "globals": { "BananaSkin": true } } ``` In TypeScript, `!` after a field name indicates a *definite assignment assertion*. Because `!` only applies to fields, is a syntax error to write `!` after a method name: ```typescript class Banana { skin!: BananaSkin | undefined; peel!() { this.skin = undefined; } } ``` To fix this error, remove the `!`: ```typescript class Banana { skin!: BananaSkin | undefined; peel() { this.skin = undefined; } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0241.md # E0241: newline is not allowed between field name and '!' ```config-for-examples { "globals": { "BananaSkin": true } } ``` In TypeScript, `!` after a field name indicates a *definite assignment assertion*. It is a syntax error to put the field name on a different line from `!`: ```typescript class Banana { skin !: BananaSkin | undefined; peel() { this.skin = undefined; } } ``` To fix this error, put `!` immediately after the field name, on the same line: ```typescript class Banana { skin!: BananaSkin | undefined; peel() { this.skin = undefined; } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0243.md # E0243: interfaces cannot contain static blocks `static` blocks in classes contain code which runs when the class is created at run time. Because TypeScript interfaces exist only at compile time, `static` blocks are not supported in interfaces: ```typescript class ConsoleLogger implements Logger { log(message) { console.log(message); } } let logger: Logger; interface Logger { log(message: string): void; static { logger = new ConsoleLogger(); } } ``` To fix this error, move the code in the `static` code block outside the interface, then delete the empty `static` code block: ```typescript class ConsoleLogger implements Logger { log(message) { console.log(message); } } let logger: Logger; interface Logger { log(message: string): void; } logger = new ConsoleLogger(); ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0244.md # E0244: abstract classes are not allowed in JavaScript ```config-for-examples { "globals": { "LogSeverity": true } } ``` Marking classes as `abstract` is a TypeScript feature. It is a syntax error to write `abstract` before `class` in JavaScript: ```javascript abstract class Logger { log(message) { this.logRaw(LogSeverity.INFO, message); } } class ConsoleLogger extends Logger { logRaw(severity, message) { console.log(message); } } ``` To fix this error, remove the `abstract` keyword and rely on JavaScript's dynamic typing: ```javascript class Logger { log(message) { this.logRaw(LogSeverity.INFO, message); } } class ConsoleLogger extends Logger { logRaw(severity, message) { console.log(message); } } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0245.md # E0245: missing body for TypeScript interface ```config-for-examples { "globals": { "log": true } } ``` TypeScript interfaces require a body, which must be a list of field and method signatures surrounded by `{` and `}`. It is a syntax error to omit the body of a interface: ```typescript // Tag interfaces interface Hidden {} interface Unsafe interface Logger; { log(); } ``` To fix this error, write the body of the class, including `{` and `}`: ```typescript class Hidden {} class Unsafe {} ``` Alternatively, remove the stray `;` before `{`: ```typescript interface Logger { log(); } ``` Introduced in quick-lint-js version 2.6.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0246.md # E0246: 'extends' must be before 'implements' TypeScript classes can extend another class and implement interfaces. It is a syntax error to write the implemented interfaces before the extended class: ```typescript import stream from "node:stream"; class MyStream implements stream.ReadableStream extends stream.Stream { // ... } ``` To fix this error, write the `extends` clause before the `implements` clause: ```typescript import stream from "node:stream"; class MyStream extends stream.Stream implements stream.ReadableStream { // ... } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0247.md # E0247: TypeScript 'implements' is not allowed in JavaScript TypeScript interfaces are not supported in JavaScript. Therefore, using `implements` on a JavaScript class is a syntax error: ```javascript import stream from "node:stream"; class MyStream extends stream.Stream implements stream.ReadableStream { // ... } class DownloadError implements Error { constructor(url) { super(`Downloading ${url} failed`); } } ``` To fix this error, remove the `implements` clause: ```javascript import stream from "node:stream"; class MyStream extends stream.Stream { // ... } ``` Alternatively, replace `implements` with `extends` to inherit a class: ```javascript class DownloadError extends Error { constructor(url) { super(`Downloading ${url} failed`); } } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0248.md # E0248: extra ',' is not allowed between enum members In a TypeScript enum, members are separated with commas. It is a syntax error to write more than one comma between enum members: ```typescript enum LogLevel { DEBUG,, , WARNING, ERROR, } ``` To fix this error, remove the extra commas: ```typescript enum LogLevel { DEBUG, WARNING, ERROR, } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0249.md # E0249: computed enum member name must be a simple string TypeScript enum members can be named using a string literal. The string literal must not contain parentheses, concatenation, or anything other than a basic string: ```typescript enum LogLevel { // Our obfuscation scripts get confused by the // term "DEBUG" here, so work around it with +. ['DE' + 'BUG'] = 'DE' + 'BUG', } ``` To fix this error, simplify the member name into a string literal: ```typescript enum LogLevel { // Our obfuscation scripts get confused by the // term "DEBUG" here, so work around it with // a Unicode escape sequence. ['DE\u{66}UG'] = 'DE\u{66}UG', } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0250.md # E0250: enum member name cannot be numeric TypeScript enum members can be named using an identifier or a string literal. It is a syntax error to name an enum member using a number literal: ```typescript enum LogLevel { ERROR = 0, WARNING = 1, INFO = 2, // For array-like access: 0 = 0, 1 = 1, 2 = 2, } ``` To fix this error, replace the enum with an object: ```typescript const LogLevel = { ERROR: 0, WARNING: 1, INFO: 2, // For array-like access: 0: 0, 1: 1, 2: 2, } as const; ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0251.md # E0251: enum value must be a compile-time constant ```config-for-examples { "globals": { "getDefaultLogLevel": true } } ``` In TypeScript, normal enums can contain computed values. However, enums declared with `const enum`, `declare enum`, or `declare const enum` must only contain compile-time constants. It is an error to write a non-constant value in an enum which requires constant values: ```typescript declare enum LogLevel { ERROR = 1, INFO = 2, DEBUG = 3, DEFAULT = getDefaultLogLevel(), } ``` To fix this error, convert the enum member into a variable: ```typescript declare enum LogLevel { ERROR = 1, INFO = 2, DEBUG = 3, } const DEFAULT_LOG_LEVEL: LogLevel = getDefaultLogLevel(); ``` Alternatively, use a normal enum: ```typescript enum LogLevel { ERROR = 1, INFO = 2, DEBUG = 3, DEFAULT = getDefaultLogLevel(), } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0252.md # E0252: enum member needs initializer; computed value disables enum autoincrement ```config-for-examples { "globals": { "getDefaultLogLevel": true } } ``` In a TypeScript enum, if there is a member with a computed value, the following member must have an explicit value. It is an error to write an autoincrement enum member (i.e. one without a value) after a member with a computed value: ```typescript enum LogLevel { DEFAULT = getDefaultLogLevel(), DEBUG, INFO, ERROR, } ``` To fix this error, write a value for the enum member: ```typescript enum LogLevel { DEFAULT = getDefaultLogLevel(), DEBUG = 0, INFO, ERROR, } ``` Alternatively, move the member with a computed value after the autoincrement members: ```typescript enum LogLevel { DEBUG, INFO, ERROR, DEFAULT = getDefaultLogLevel(), } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0253.md # E0253: use ':' instead of '=' in object literals JavaScript object literals are key-value pairs. In an expression, it is a syntax error to write `=` instead of `:` between the key and the value in an object literal: ```javascript import fs from 'node:fs/promises'; await fs.mkdir("build/temp", { recursive = true }); ``` To fix this error, replace `=` with `:`: ```javascript import fs from 'node:fs/promises'; await fs.mkdir("build/temp", { recursive: true }); ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0254.md # E0254: unexpected ':' in expression; did you mean 'as'? ```config-for-examples { "globals": { "uri": true } } ``` In TypeScript, `:` is used to add a type annotation to variables. It is a syntax error to write `:` in an expression: ```typescript interface APIResponse { data: object; error?: string; } let data = await (await fetch(uri)).json(): APIResponse; ``` To fix this error, write `as` instead of `:`: ```typescript interface APIResponse { data: object; error?: string; } let data = await (await fetch(uri)).json() as APIResponse; ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0255.md # E0255: missing parentheses around parameter; TypeScript type annotation requires parentheses ```config-for-examples { "globals": { "Friend": true, "friends": true } } ``` Arrow functions with one parameter can omit the parentheses around that parameter. However, if the parameter has a type annotation, it is a syntax error to omit the parentheses: ```typescript let friendNames = friends.map(f: Friend => f.name); const toString = thing: string => { if (thing === true) return 'TRUE'; if (thing === false) return 'FALSE'; return thing.toString(); }; ``` To fix this error, put a pair of parentheses around the parameter name and its type: ```typescript let friendNames = friends.map((f: Friend) => f.name); ``` Alternatively, put a pair of parentheses around the parameter name, and leave the `:` and the return type outside: ```typescript const toString = (thing): string => { if (thing === true) return 'TRUE'; if (thing === false) return 'FALSE'; return thing.toString(); }; ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0256.md # E0256: catch variable can only be typed as '\*', 'any', or 'unknown' ```config-for-examples { "globals": { "fs": true, "ConfigError": true } } ``` In TypeScript, a `catch` variable can be annotated with either no type, `*`, `any`, or `unknown`. It is an error to annotate a `catch` variable with a specific error type: ```typescript function loadConfig(path) { let json = fs.readFileSync(path, "utf-8"); try { return JSON.parse(json); } catch (e: SyntaxError) { console.warn(`failed to load config: ${e}`); return null; } } ``` To fix this error, annotate the `catch` variable with the `unknown` type, then use `instanceof` to check the error's type at run time: ```typescript function loadConfig(path) { let json = fs.readFileSync(path, "utf-8"); try { return JSON.parse(json); } catch (e: unknown) { if (e instanceof SyntaxError) { console.warn(`failed to load config: ${e}`); return null; } else { throw e; } } } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0257.md # E0257: missing ',', ';', or newline between object type entries In TypeScript, properties in object types are separated by commas, semicolons, or newlines. It is a syntax error to write two properties without one of those separators in between: ```typescript type Status = { ok: boolean error?: string }; ``` To fix this error, add a separator between the two properties: ```typescript type Status = { ok: boolean, error?: string }; ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0258.md # E0258: missing type between '|' and '|' (or '&' and '&') An extra `|` or `&` is allowed at the beginning of a TypeScript type. However, it is a syntax error to write an extra `|` or `&` in the middle of a TypeScript type: ```typescript type Primitive = | string | number | bigint | boolean | null | | undefined ``` To fix this error, remove the extra `|` or `&`: ```typescript type Primitive = | string | number | bigint | boolean | null | undefined ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0259.md # E0259: '.' is not allowed after generic arguments In TypeScript types, you can look up a property of a generic type using `Type["name"]` syntax. It is a syntax error to instead use `.` to look up a property of a generic type: ```typescript class Thing { static thong: number; } type ThingThong = typeof Thing.thong; ``` To fix this error, write `["name"]` instead of `.name`: ```typescript class Thing { static thong: number; } type ThingThong = typeof Thing["thong"]; ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0260.md # E0260: TypeScript non-null assertion is not allowed on parameters In TypeScript, `!` after an expression is a *non-null assertion*. It is a syntax error to write a non-null assertion after a function parameter: ```typescript // color cannot be null. function colorToHexCode(color!: string): string { switch (color) { // ... } } ``` To fix this error, remove the `!` and ensure the parameter's type does not include `null`: ```typescript // color cannot be null. function colorToHexCode(color: string): string { switch (color) { // ... } } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0261.md # E0261: TypeScript non-null assertions are not allowed in JavaScript ```config-for-examples { "globals": { "DoggieTail": true, "player": true } } ``` In TypeScript, `!` after a expression is a *non-null assertion*. It is a syntax error to write a non-null assertion in JavaScript: ```javascript /** @type {string} favoritePowerRanger */ let favoritePowerRanger; if (player.hasFavoriteColor) { favoritePowerRanger = player.favoriteColor!; } else { favoritePowerRanger = "(unknown)"; } ``` To fix this error, remove the `!`: ```javascript /** @type {string} favoritePowerRanger */ let favoritePowerRanger; if (player.hasFavoriteColor) { favoritePowerRanger = player.favoriteColor; } else { favoritePowerRanger = "(unknown)"; } ``` Introduced in quick-lint-js version 2.7.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0262.md # E0262: leading commas are not allowed in generic parameter lists In a TypeScript generic class, function, or type alias, the generic parameter list is a comma-separated list of variables surrounded by `<` and `>`. It is a syntax error for the parameter list to start with an extra comma: ```typescript class MagicMap< , Key , Value > { // ... } ``` To fix this error, remove the leading `,`: ```typescript class MagicMap < Key , Value > { // ... } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0263.md # E0263: only one comma is allowed between or after generic parameters ```config-for-examples { "globals": { "HashMap": true, "DefaultHasher": true } } ``` In a TypeScript generic class, function, or type alias, the generic parameter list is a comma-separated list of variables surrounded by `<` and `>`. It is a syntax error for the parameter list to have doubled commas: ```typescript class HashMap { // ... } function makeHashMap( ): HashMap { return new HashMap(new DefaultHasher()); } ``` To fix this error, write a type variable name between the commas: ```typescript class HashMap { // ... } ``` Alternatively, remove the extra comma: ```typescript function makeHashMap( ): HashMap { return new HashMap(new DefaultHasher()); } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0264.md # E0264: expected at least one parameter in generic parameter list ```config-for-examples { "globals": { "APIResult": true, "T": true } } ``` In a TypeScript generic class, function, or type alias, the generic parameter list is a comma-separated list of variables surrounded by `<` and `>`. It is a syntax error for the parameter list to be empty: ```typescript function api<>(endpoint: string): APIResult { // ... } function flattenArray<>(arrays: T[][]): T[] { // ... } ``` To fix this error, remove `<` and `>`: ```typescript function api(endpoint: string): APIResult { // ... } ``` Alternatively, write a type variable name inside the brackets: ```typescript function flattenArray(arrays: T[][]): T[] { // ... } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0265.md # E0265: missing comma between generic parameters In a TypeScript generic class, function, or type alias, the generic parameter list is a comma-separated list of variables surrounded by `<` and `>`. It is a syntax error to omit a comma between generic parameters: ```typescript class MagicMap< Key extends string|number Value > { // ... } ``` To fix this error, write a comma between the two generic parameters: ```typescript class MagicMap< Key extends string|number, Value > { // ... } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0266.md # E0266: redundant 'await' ```config-for-examples { "globals": { "fs": true, "tempDir": true, "uri": true } } ``` The `await` operator unwraps a `Promise`, giving you the value when the `Promise` is resolved. Because a `Promise` cannot resolve to another `Promise`, `await` will never give you a `Promise` object. Therefore, using `await` on the result of `await` is redundant: ```javascript await await fs.promises.rmdir(tempDir); let data = await await fetch(uri).json(); ``` To fix this error, delete the redundant `await` operator: ```javascript await fs.promises.rmdir(tempDir); ``` Alternatively, wrap the inner `await` expression in parentheses: ```javascript let data = await (await fetch(uri)).json(); ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0267.md # E0267: TypeScript types are not allowed in JavaScript TypeScript type aliases can be declared with the `type` keyword. It is a syntax error to write a TypeScript type alias in JavaScript code: ```javascript type Response = { ok: boolean; error?: string; data?: T; }; ``` To fix this error, rename your file to have a `.ts` or `.tsx` suffix. Alternatively, use JSDoc to declare the type: ```javascript /** * @typedef {Object} Response * @prop {boolean} ok * @prop {string} [error] * @prop {Object} data */ ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0268.md # E0268: TypeScript type imports cannot import both default and named exports In TypeScript, `import type` can be used to import types from another module. It is a syntax error to use `import type` to import both a default export (outside `{` and `}`) and some named exports (inside `{` and `}`): ```typescript import type Styles, {StyleMap} from "./Styles"; ``` To fix this error, split the import into two: ```typescript import type Styles from "./Styles"; import type {StyleMap} from "./Styles"; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0269.md # E0269: 'async static' is not allowed; write 'static async' instead ```config-for-examples { "globals": { "mysql": true } } ``` Class methods can have modifiers such as `static`, `async`, and `*`. It is a syntax error to write `async static` in a class method declaration: ```javascript class Database { async static connect(host, login, database) { let db = await mysql.connect(host, login); await db.use(database); return new Database(db); } } ``` To fix this error, replace `async static` with `static async`: ```javascript class Database { static async connect(host, login, database) { let db = await mysql.connect(host, login); await db.use(database); return new Database(db); } } ``` Introduced in quick-lint-js version 0.3.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0270.md # E0270: TypeScript type imports are not allowed in JavaScript TypeScript supports importing types using `import type`. It is a syntax error to write `import type` in JavaScript code: ```javascript import React, {type FC} from "react"; ``` To fix this error, delete the imported type: ```javascript import React from "react"; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0271.md # E0271: TypeScript type imports are not allowed in JavaScript This error has been renamed to E0270. Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0272.md # E0272: 'type' cannot be used twice in import When importing in TypeScript, `type` can be used to indicate that the symbol should not be imported at run time. It is a syntax error to mix both `import type ...` and `import {type ...}`: ```typescript import type { ChangeEvent, createElement, type FC, } from "react"; ``` To fix this error, use only the `import {type ...}` syntax: ```typescript import { type ChangeEvent, createElement, type FC, } from "react"; ``` Alternatively, use only the `import type ...` syntax, importing twice if you also need run time imports: ```typescript import type { ChangeEvent, FC } from "react"; import { createElement } from "react"; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0273.md # E0273: TypeScript namespaces are not allowed in JavaScript TypeScript supports namespaces to describe objects. JavaScript does not support this syntax. It is a syntax error to use TypeScript's `namespace` keyword to create a namespace in JavaScript: ```javascript namespace goog { export class Chart { // ... } } ``` To fix this error, create a variable with an object instead: ```javascript const goog = {}; goog.Chart = class Chart { // ... }; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0274.md # E0274: TypeScript import aliases are not allowed in JavaScript TypeScript supports import alias using `import`. It is a syntax error to write such an alias in JavaScript code: ```javascript import m = require('mod'); ``` To fix this error, use `const` instead of `import`: ```javascript const m = require('mod'); ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0275.md # E0275: newline is not allowed after 'interface' In TypeScript, the `interface` keyword must be followed by the interface's name. It is a syntax error to write a newline between `interface` and the following name: ```typescript interface HashMap { get(k: Key): Value; } ``` To fix this error, put the interface's name on the same line as the `interface` keyword: ```typescript interface HashMap { get(k: Key): Value; } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0276.md # E0276: newline is not allowed after 'namespace' In TypeScript, the `namespace` keyword must be followed by the namespace's name. It is a syntax error to write a newline between `namespace` and the following name: ```typescript namespace reallyLongNamespaceName { export class Error {} } ``` To fix this error, put the namespace's name on the same line as the `namespace` keyword: ```typescript namespace reallyLongNamespaceName { export class Error {} } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0277.md # E0277: newline is not allowed after 'type' In TypeScript, the `type` keyword must be followed by the type's name. It is a syntax error to write a newline between `type` and the following name: ```typescript export type ReallyLongTypeAliasName = number; ``` To fix this error, put the type alias' name on the same line as the `type` keyword: ```typescript type ReallyLongTypeAliasName = number; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0278.md # E0278: TypeScript type exports are not allowed in JavaScript TypeScript supports exporting types using `export type`. It is a syntax error to write `export type` in JavaScript code: ```javascript // Warning: Do not instantiate directly. // Use makeBanana instead. class Banana { } // Don't allow instantiating Bananas directly. export type {Banana}; /** @returns {Banana} */ export function makeBanana() { return new Banana(); } ``` To fix this error, export the variable normally by removing the `type` keyword: ```javascript // Warning: Do not instantiate directly. // Use makeBanana instead. class Banana { } export {Banana}; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0279.md # E0279: TypeScript type exports are not allowed in JavaScript This error has been renamed to E0279. Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0280.md # E0280: 'type' cannot be used twice in export ```config-for-examples { "globals": { "ChangeEvent": true, "FC": true, "createElement": true } } ``` When exporting in TypeScript, `type` can be used to indicate that the symbol should not be exported at run time. It is a syntax error to mix both `export type ...` and `export {type ...}`: ```typescript export type { ChangeEvent, createElement, type FC, }; ``` To fix this error, use only the `export {type ...}` syntax: ```typescript export { type ChangeEvent, createElement, type FC, }; ``` Alternatively, use only the `import type ...` syntax, exporting twice if you also need run time exports: ```typescript export type { ChangeEvent, FC }; export { createElement }; ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0281.md # E0281: TypeScript 'as' type assertions are not allowed in JavaScript ```config-for-examples { "globals": { "container": true } } ``` In TypeScript, the `as` operator is a *type assertion* which reinterprets a value with a different type at compile time. It is a syntax error to use the `as` operator in JavaScript code: ```javascript let avatar = container.querySelector(".avatar") as Image; ``` To fix this error, remove `as` and the type: ```javascript let avatar = container.querySelector(".avatar"); ``` Alternatively, rename your file to have a `.ts` or `.tsx` suffix. Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0282.md # E0282: use ':' instead of 'as' to type a function parameter The `as` operator is not allowed in function parameters. It is a syntax error to use `as` to annotate a parameter with a type: ```typescript function reversed(array as T[]): T[] { return [...array].reverse(); } ``` To fix this error, write `:` instead of `as`: ```typescript function reversed(array: T[]): T[] { return [...array].reverse(); } ``` Introduced in quick-lint-js version 2.8.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0283.md # E0283: TypeScript <Type> casts are not allowed in JSX mode ```config-for-examples { "globals": { "useEffect": true } } ``` TypeScript supports two styles for type assertions: `variable` and `variable as Type`. It is a syntax error to use the former style in a `.tsx` file: ```typescript-jsx interface Payload { data: string; } interface PayloadError { error: string; } function useFetchPayload(uri, onResult) { useEffect(async () => { let data = await (await fetch(uri)).json(); onResult(data); }, [uri]); } ``` To fix this error, use `as` instead: ```typescript-jsx interface Payload { data: string; } interface PayloadError { error: string; } function useFetchPayload(uri, onResult) { useEffect(async () => { let data = await (await fetch(uri)).json(); onResult(data as Payload | PayloadError); }, [uri]); } ``` Introduced in quick-lint-js version 2.9.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0284.md # E0284: missing TypeScript type In TypeScript, you can annotate the type of a variable by writing `:` after its name in its declaration. It is a syntax error to omit the type after `:`: ```typescript function api(endpoint: ): Promise { // ... } ``` To fix this error, write a type after the `:`: ```typescript function api(endpoint: string): Promise { // ... } ``` Alternatively, remove the `:`: ```typescript function api(endpoint): Promise { // ... } ``` Introduced in quick-lint-js version 2.9.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0285.md # E0285: generic arrow function needs ',' here in TSX In TypeScript, generic arrow functions have syntax like `(params) => body`. In JSX, elements have syntax like `{children}`. Because of a possible ambiguity, generic arrow functions in TypeScript+JSX must have at least one comma inside the parameter list: ```typescript-jsx const reversed = (array: T[]) => [...array].reverse(); ``` To fix this error, add a comma after the generic parameter: ```typescript-jsx const reversed = (array: T[]) => [...array].reverse(); ``` Alternatively, write a normal function instead of an arrow function: ```typescript-jsx function reversed(array: T[]) { return [...array].reverse(); } ``` Introduced in quick-lint-js version 2.9.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0286.md # E0286: lower case letters compared with toUpperCase Comparing the result of a function named `toUpperCase` to a string literal with one or more lower case letters will always yield the same result. ```javascript let x = "BaNaNa"; // always returns 'false' if (x.toUpperCase() === "banana") { } // always returns 'true' if (x.toUpperCase() !== "banana") { } ``` Introduced in quick-lint-js version 2.9.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0287.md # E0287: upper case letters compared with toLowerCase Comparing the result of a function named `toLowerCase` to a string literal with one or more upper case letters will always yield the same result. ```javascript let x = "BaNaNa"; // always returns 'false' if (x.toLowerCase() === "BANANA") { } // always returns 'true' if (x.toLowerCase() !== "BANANA") { } ``` Introduced in quick-lint-js version 2.9.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0288.md # E0288: TypeScript interface properties are always public and cannot be marked protected TypeScript interfaces describe the properties of objects usable from outside that object's class. Therefore, all interface properties must be public. It is an error to declare a protected property in an interface: ```typescript interface Painter { paintPixel(pos, color); protected doPaintPixel(pos, color); } class CanvasPainter implements Painter { paintPixel(pos, color) { this.validatePixel(pos); this.doPaintPixel(pos, color); } private validatePixel(pos) { // ... } protected doPaintPixel(pos, color) { // ... } } ``` To fix this error, remove the `protected` keyword from the interface property. Alternatively, delete the protected property entirely from the interface. Alternatively, convert the interface into an abstract class: ```typescript abstract class Painter { paintPixel(pos, color) { this.validatePixel(pos); this.doPaintPixel(pos, color); } private validatePixel(pos) { // ... } protected abstract doPaintPixel(pos, color); } class CanvasPainter extends Painter { protected doPaintPixel(pos, color) { // ... } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0289.md # E0289: 'public' is not allowed in JavaScript JavaScript properties are public by default. It is a syntax error to write `public` explicitly: ```javascript class Vec2D { public x = 0; public y = 0; public length() { return Math.sqrt( this.x * this.x + this.y * this.y); } } ``` To fix this error, remove the `public` keyword: ```javascript class Vec2D { x = 0; y = 0; length() { return Math.sqrt( this.x * this.x + this.y * this.y); } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0290.md # E0290: assignment-assertion fields cannot have default values ```config-for-examples { "globals": { "BananaSkin": true } } ``` In TypeScript, `!` after a field name indicates a *definite assignment assertion*. It is a syntax error to initialize such a field: ```typescript class Banana { skin!: BananaSkin | undefined = undefined; peel() { this.skin = undefined; } } ``` To fix this error, remove the `!`: ```typescript class Banana { skin: BananaSkin | undefined = undefined; peel() { this.skin = undefined; } } ``` Alternatively, remove the initializer: ```typescript class Banana { skin!: BananaSkin | undefined; peel() { this.skin = undefined; } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0291.md # E0291: 'as const' is only allowed on literals (array, object, string, boolean) and enum members ```config-for-examples { "globals": { "html": true } } ``` In TypeScript, `as const` types an expression with a literal type. Expressions which can have literal types include the following: * Array literals (e.g. `[]`, `[first, second, third]`) * Object literals (e.g. `{}`, `{ key: value }`) * String literals (e.g. `''`, `'hello'`) * Untagged template literals (e.g. \`\`, \`hello\`) * `true` * `false` * Enum members (e.g. `LogLevel.DEBUG`) * Any of the above wrapped in parentheses It is an error to use `as const` on an expression which cannot have a literal type: ```typescript const DOCTYPE = html`` as const; ``` To fix this error, remove `as const`: ```typescript const DOCTYPE = html``; ``` Alternatively, change the expression so it is valid with `as const`: ```typescript const DOCTYPE = `` as const; ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0292.md # E0292: missing semicolon after interface method TypeScript methods in interfaces must end with either a semicolon (`;`) or a newline. It is a syntax error to omit the semicolon and write something on the same line after the method: ```typescript interface Container { getItem(key: string): number | string void; } ``` To fix this error, write a correct type for the method: ```typescript interface Container { getItem(key: string): number | string | void; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0293.md # E0293: missing semicolon after abstract method TypeScript abstract methods in classes do not have bodies. Therefore, they must end with either a semicolon (`;`) or a newline. It is a syntax error to omit the semicolon and write something on the same line after the abstract method: ```typescript abstract class Container { abstract getItem(key: string): number | string void; } ``` To fix this error, write a correct type for the method: ```typescript abstract class Container { abstract getItem(key: string): number | string | void; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0294.md # E0294: abstract methods cannot contain a body ```config-for-examples { "globals": { "LogLevel": true } } ``` TypeScript abstract methods in classes do not have bodies. It is a syntax error to write a method body for a method marked `abstract`: ```typescript abstract class Logger { // Implement this in subclasses. protected abstract logRaw( severity: LogLevel, message: string, ); abstract log(message: string) { this.logRaw(LogLevel.INFO, message); } } class ConsoleLogger extends Logger { protected logRaw( severity: LogLevel, message: string, ) { console.log(message); } } ``` To fix this error, remove the `abstract` keyword: ```typescript abstract class Logger { // Implement this in subclasses. protected abstract logRaw( severity: LogLevel, message: string, ); log(message: string) { this.logRaw(LogLevel.INFO, message); } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0295.md # E0295: abstract fields cannot have default values TypeScript abstract fields in classes cannot have initializers. It is a syntax error to write an initializer for a field marked `abstract`: ```typescript abstract class Expression { abstract readonly op: string = "???"; left!: Expression; right!: Expression; toString(): string { return `${this.left} ${this.op} ${this.right}`; } abstract eval(): any; } class AddExpression { readonly op: string = "+"; eval(): any { return this.left.eval() + this.right.eval(); } } ``` To fix this error, remove the initializer: ```typescript abstract class Expression { abstract readonly op: string; left!: Expression; right!: Expression; /* ... */ } ``` Alternatively, keep the initializer but remove the `abstract` keyword: ```typescript abstract class Expression { readonly op: string = "???"; left!: Expression; right!: Expression; /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0296.md # E0296: abstract properties are only allowed in abstract classes ```config-for-examples { "globals": { "LogLevel": true } } ``` TypeScript abstract classes can contain abstract methods and fields. It is a syntax error to write an abstract method or field in a class not marked `abstract`: ```typescript class Logger { // Implement this in subclasses. abstract log( severity: LogLevel, message: string, ); } class ConsoleLogger extends Logger { log( severity: LogLevel, message: string, ) { console.log(`${severity}: ${message}`); } } ``` To fix this error, add the `abstract` keyword to the class: ```typescript abstract class Logger { // Implement this in subclasses. abstract log( severity: LogLevel, message: string, ); } ``` Alternatively, make the method non-abstract by removing the `abstract` keyword and giving it a body: ```typescript abstract class Logger { // Optionally implement this in subclasses. log( severity: LogLevel, message: string, ) { // Default behavior: do not log. } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0297.md # E0297: abstract properties are not allowed in interfaces ```config-for-examples { "globals": { "LogLevel": true } } ``` TypeScript abstract classes can contain abstract methods and fields. Interface methods and fields are automatically abstract. It is a syntax error to write `abstract` for an interface method or field: ```typescript interface Logger { abstract log( severity: LogLevel, message: string, ); } class ConsoleLogger implements Logger { log( severity: LogLevel, message: string, ) { console.log(`${severity}: ${message}`); } } ``` To fix this error, remove the `abstract` keyword: ```typescript interface Logger { log( severity: LogLevel, message: string, ); } ``` Alternatively, convert the interface into an abstract class: ```typescript abstract class Logger { abstract log( severity: LogLevel, message: string, ); } class ConsoleLogger extends Logger { log( severity: LogLevel, message: string, ) { console.log(`${severity}: ${message}`); } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0298.md # E0298: abstract methods cannot be marked 'async' ```config-for-examples { "globals": { "LoadedData": true } } ``` The `async` keyword on methods changes the body of that method. Abstract methods do not have bodies. Therefore, `async` does not make sense on abstract methods, and it is a syntax error to write it: ```typescript abstract class DataLoader { abstract async load(): Promise; } ``` To fix this error, remove the `async` keyword: ```typescript abstract class DataLoader { abstract load(): Promise; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0299.md # E0299: abstract methods cannot be marked as a generator ```config-for-examples { "globals": { "Generator": true } } ``` `*` on a method allows using the `yield` keyword in the body of the method. Abstract class methods do not have bodies. Therefore, `*` does not make sense on abstract methods, and it is a syntax error to write it: ```typescript abstract class RandomSource { abstract *makeRandomNumbers(): Generator; } ``` To fix this error, remove the `*`: ```typescript abstract class RandomSource { abstract makeRandomNumbers(): Generator; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0300.md # E0300: newline is not allowed after 'abstract' In TypeScript, the `abstract` keyword can be used to mark a class as abstract. It is an error to put a line break between the `abstract` keyword and the `class` keyword: ```typescript export abstract class Logger { abstract log(message: string); } ``` To fix this error, put `abstract` and `class` on the same line: ```typescript export abstract class Logger { abstract log(message: string); } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0301.md # E0301: 'this' parameters are not allowed in arrow functions ```config-for-examples { "globals": { "DB": true, "db": true, "User": true } } ``` TypeScript allows you to add a type annotation to the implicit `this` parameter explicitly. This is possible in methods, in functions declared with the `function` keyword, and in function types. It is a syntax error to write a `this` parameter explicitly in an arrow function: ```typescript // Example from TypeScript documentation. SPDX license: MIT // Copyright (c) Microsoft Corporation interface DB { filterUsers(filter: (this: User) => boolean): User[]; } let admins = db.filterUsers((this: User) => { return this.admin; }); ``` To fix this error, write a function with the `function` keyword instead of an arrow function: ```typescript let admins = db.filterUsers(function (this: User) { return this.admin; }); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0302.md # E0302: 'this' parameter not allowed when destructuring ```config-for-examples { "globals": { "Ring": true, "his": true, "hisRing": true, "herRing": true } } ``` TypeScript allows you to explicitly declare the `this` parameter. It is a syntax error to destructure the `this` parameter or to include the `this` parameter when destructuring another parameter: ```typescript function swapRings([this, hers]) { return [hers, his]; } let newRings = swapRings([hisRing, herRing]); ``` To fix this error, name the parameter something other than `this`: ```typescript function swapRings([his, hers]) { return [hers, his]; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0303.md # E0303: 'this' must be the first parameter TypeScript allows you to explicitly declare the `this` parameter. It is a syntax error to write another parameter before the `this` parameter: ```typescript $("form button").each(function ( index: number, this: Element, ) { console.log(`disabling button #${index}`); $(this).disable(); }); ``` To fix this error, move `this` to the start of the parameter list: ```typescript $("form button").each(function ( this: Element, index: number, ) { console.log(`disabling button #${index}`); $(this).disable(); }); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0304.md # E0304: cannot use '...' on 'this' parameter ```config-for-examples { "globals": { "args": true } } ``` TypeScript allows you to explicitly declare the `this` parameter. It is a syntax error to use `...` (spread) on the `this` parameter: ```typescript function log(message: string, ...this: unknown[]) { console.log(`${new Date}: ${message}`, args); } ``` To fix this error, rename the parameter to something other than `this`: ```typescript function log(message: string, ...args: unknown[]) { console.log(`${new Date}: ${message}`, args); } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0305.md # E0305: 'this' parameters are not allowed in JavaScript TypeScript allows you to explicitly declare the `this` parameter. It is a syntax error to declare the `this` parameter in JavaScript code: ```javascript $("form button").each(function (this, index) { console.log(`disabling button #${index}`); $(this).disable(); }); $("form button").each((this, index) => { console.log(`enabling button #${index}`); $(this).enable(); }); ``` To fix this error, remove the `this` parameter: ```javascript $("form button").each(function (index) { console.log(`disabling button #${index}`); $(this).disable(); }); ``` Alternatively, convert the arrow function into a function declared with the `function` keyword and also remove the `this` parameter: ```javascript $("form button").each(function (index) { console.log(`enabling button #${index}`); $(this).enable(); }); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0306.md # E0306: React/JSX is not allowed in vanilla TypeScript code ```config-for-examples { "globals": { "React": true, "ReactDOM": true } } ``` Vanilla TypeScript does not support JSX syntax (used in React code). It is a syntax error to create a JSX element or JSX fragment in vanilla TypeScript: ```typescript ReactDOM.render(

    Hello, world!

    , document.getElementById('root') ); ``` To fix this error, rename your `.ts` file to have a `.tsx` suffix instead. Alternatively, use `React.createElement` instead of JSX syntax: ```typescript ReactDOM.render( React.createElement( 'h1', {className: 'title'}, 'Hello, world!', ), document.getElementById('root'), ); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0307.md # E0307: unexpected '?' In JavaScript, `?` is used for the conditional operator (e.g. `haveEggs ? takeEgg() : null`). In TypeScript, `?` is also used for optional properties and parameters. It is a syntax error to write `?` in other contexts: ```javascript class EggBasket { maybeTakeEgg() { return this.haveEggs ? } get haveEggs() { /* ... */ } removeEgg() { /* ... */ } } ``` To fix this error, complete the conditional expression: ```javascript class EggBasket { maybeTakeEgg() { return this.haveEggs ? this.removeEgg() : null; } /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0308.md # E0308: TypeScript optional parameters are not allowed in JavaScript ```config-for-examples { "globals": { "getDefaultOptions": true } } ``` In TypeScript, parameters can be explicitly marked as optional. It is a syntax error to write `?` to mark a parameter optional in JavaScript: ```javascript async function download(uri, options?) { options ||= getDefaultOptions(); /* ... */ } ``` In JavaScript, all parameters are optional. To fix this syntax error, remove `?` from the parameter: ```javascript async function download(uri, options) { options ||= getDefaultOptions(); /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0309.md # E0309: unexpected '?' when destructuring In TypeScript, `?` can be used to mark a function parameter as optional. It is a syntax error to write `?` when destructuring: ```typescript type OneOrTwo = [T] | [T, T]; function join1Or2( [first, second?]: OneOrTwo, ) { return second ? first+second : first; } ``` To fix this error, remove the `?`: ```typescript type OneOrTwo = [T] | [T, T]; function join1Or2( [first, second]: OneOrTwo, ) { return second ? first+second : first; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0310.md # E0310: optional parameter cannot have both '?' and initializer; remove '?' In TypeScript, parameters can be explicitly marked as optional with `?`. It is a syntax error to write a default initializer for a parameter marked optional with `?`: ```typescript async function download(uri, options? = {}) { /* ... */ } ``` Parameters with default initializers are always optional. To fix this syntax error, remove the redundant `?`: ```typescript async function download(uri, options = {}) { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0311.md # E0311: missing parentheses around parameter; TypeScript optional parameter requires parentheses In TypeScript, parameters can be explicitly marked as optional with `?`. It is a syntax error to write an arrow function with an optional parameter without parentheses around the parameter list: ```typescript const error = message? => { throw new Error(message); }; ``` To fix this error, write parentheses around the parameter list: ```typescript const error = (message?) => { throw new Error(message); }; ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0312.md # E0312: missing parentheses around parameter; TypeScript optional parameter with type annotation requires parentheses ```config-for-examples { "globals": { "fs": true, "outputPath": true, "result": true } } ``` In TypeScript, parameters can be explicitly marked as optional and can have type annotations. It is a syntax error to write an arrow function with a typed optional parameter without parentheses around the parameter list: ```typescript fs.promises.writeFile(outputPath, result) .then(async err?: Error => { if (err) throw err; }); ``` To fix this error, write parentheses around the parameter list: ```typescript fs.promises.writeFile(outputPath, result) .then(async (err?: Error) => { if (err) throw err; }); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0313.md # E0313: 'readonly' only works with array types and tuple types ```config-for-examples { "globals": { "User": true, "Player": true, "Readonly": true } } ``` In TypeScript, array types and tuple types can be marked `readonly`, which prevents methods like `.push` from being called on the array. It is a syntax error to use `readonly` on something which is not an array or tuple type: ```typescript function isVerified(user: readonly User) { return user.verificationDate !== null; } const nudge = ( players: readonly Player, dx: number, dy: number, ) => players.map(p => ({...p, /* ... */ })); ``` To fix this error, replace `readonly Type` with `Readonly`: ```typescript function isVerified(user: Readonly) { return user.verificationDate !== null; } ``` Alternatively, make the type an array type by adding `[]`: ```typescript const nudge = ( players: readonly Player[], dx: number, dy: number, ) => players.map(p => ({...p, /* ... */ })); ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0315.md # E0315: (name) is not the name of a parameter ```config-for-examples { "globals": { "user": true, "User": true, "AdminUser": true } } ``` After a function's parameter list, you can write a TypeScript type predicate (using `is`) instead of a return type. It is an error for the type predicate to refer to a variable which is not a parameter: ```typescript function isError(error: unknown): erorr is Error { return error instanceof Error; } function isAdminUser( user: User | null, ): AdminUser is user { return user && user.isAdministrator; } ``` To fix this error, fix the typo in the parameter name: ```typescript function isError(error: unknown): error is Error { return error instanceof Error; } ``` Alternatively, flip the parameter name with the type: ```typescript function isAdminUser( user: User | null, ): user is AdminUser { return user && user.isAdministrator; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0316.md # E0316: function overload signature must be named (function name) In TypeScript, functions can have overload signatures. Each signature should have the same name as the function. It is an error to write a different name in an overload: ```typescript function keys(a: T[]): number[]; function key(a: object): string[]; function keys(a: object) { if (Array.isArray(a)) { return Object.keys(a).map(k => +k); } else { return Object.keys(a); } } ``` To fix this error, write the function name correctly in each overload: ```typescript function keys(a: T[]): number[]; function keys(a: object): string[]; function keys(a: object) { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0317.md # E0317: newline is not allowed between 'async' and 'function' ```config-for-examples { "globals": { "JSONOptions": true, "StreamOptions": true, "Stream": true } } ``` Async functions have the `async` keyword followed by the `function` keyword. It is a syntax error to include a line break in between `async` and `function`: ```typescript function fetch(o: JSONOptions): Promise; function fetch(o: StreamOptions): Promise; async function fetch(options): Promise { /* ... */ } ``` To fix this error, put `function` on the same line as `async`: ```typescript function fetch(o: JSONOptions): Promise; function fetch(o: StreamOptions): Promise; async function fetch(options): Promise { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0318.md # E0318: function overload signature cannot have generator '\*' In TypeScript, functions can have overload signatures. Overload signatures work on generator functions, but it is a syntax error for an overload signature itself to have the generator `*` after the `function` keyword: ```typescript function* keys(a: T[]): number[]; function* keys(a: object): string[]; function* keys(a: object) { if (Array.isArray(a)) { for (let k in a) yield +k; } else { for (let k in a) yield k; } } ``` To fix this error, remove the `*` from the overload signatures, but keep it for the implementation: ```typescript function keys(a: T[]): number[]; function keys(a: object): string[]; function* keys(a: object) { if (Array.isArray(a)) { for (let k in a) yield +k; } else { for (let k in a) yield k; } } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0319.md # E0319: missing name for element in named tuple type In TypeScript, a tuple type can have names for each element. It is a syntax error to name some but not all tuple type elements: ```typescript function bsearch(a): [number, hi: number] { /* ... */ } ``` To fix this error, write a name for the tuple element: ```typescript function bsearch(a): [lo: number, hi: number] { /* ... */ } ``` Alternatively, delete the names of other tuple elements: ```typescript function bsearch(a): [number, number] { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0320.md # E0320: missing name for element in named tuple type In TypeScript, a tuple type can have names for each element. It is a syntax error to write `:` but omit the name in a tuple type: ```typescript function bsearch(a): [: number, hi: number] { /* ... */ } ``` To fix this error, write the name for the tuple element: ```typescript function bsearch(a): [lo: number, hi: number] { /* ... */ } ``` Alternatively, delete the `:`, and delete the names of other tuple elements: ```typescript function bsearch(a): [number, number] { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0321.md # E0321: expected '?' to mark tuple element as optional TypeScript tuple types can contain optional elements. These optional elements must be last. It is a syntax error to write a required tuple element after an optional one: ```typescript function parseVersion( ): [number, number?, string] { /* ... */ } ``` To fix this error, mark the tuple element as optional by adding `?`: ```typescript function parseVersion( ): [number, number?, string?] { /* ... */ } ``` Alternatively, use a union type: ```typescript function parseVersion( ): [number, number?] | [number, string] | [number, number, string] { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0323.md # E0323: optional tuple elements cannot come after spread elements TypeScript tuple types can contain spread elements and optional elements. However, it is a syntax error to use both a spread element and an optional element in a single tuple type: ```typescript function foo(): [...number[], string?] { /* ... */ } ``` To fix this error, use a union type instead of an optional element: ```typescript function foo(): [...number[]] | [...number[], string] { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0324.md # E0324: spread tuple elements cannot be optional ```config-for-examples { "globals": { "Options": true } } ``` TypeScript tuple types can contain spread elements. By definition, a spread element is optional. It is a syntax error to write `?` to mark a spread element as optional: ```typescript function foo(...args: [...string[]?, Options]) { /* ... */ } ``` To fix this error, remove the `?`: ```typescript function foo(...args: [...string[], Options]) { /* ... */ } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0325.md # E0325: cannot delete variables in TypeScript In JavaScript, it is possible to use `delete` on a variable. In TypeScript, deleting a variable is an error: ```typescript let x = 3; delete x; console.log(x); ``` To fix this error, remove the `delete` statement: ```typescript let x = 3; console.log(x); ``` See also: E0086 Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0326.md # E0326: 'async export' is not allowed; write 'export async' instead Functions can be marked using the `async` keyword like `async function f() {`. It is a syntax error to write the `async` keyword after the `function` keyword: ```javascript async export function f() { return 0; } ``` To fix this error, replace `async export` with `export async`: ```javascript export async function f() { return 0; } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0327.md # E0327: 'function async' is not allowed; write 'async function' instead Functions can be marked with the `async` keyword. It is a syntax error to write the `async keyword after the `function` keyword: ```javascript function async f() { return 0; } ``` To fix this error, replace `function async` with `async function`: ```javascript async function f() { return 0; } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0341.md # E0341: using '===' or '!==' against an array literal does not compare items Using the strict equality or inequality operator against an array literal will not compare the items in them, e.g. ```javascript let x = [1, 2, 3]; // the expression inside the if statement is always 'false' if (x === [1, 2, 3]) { } // the expression inside the if statement is always 'true' if (x !== [1, 2, 3]) { } ``` There are several ways to fix this warning, for example, we could compare all items manually, or, we could craft a JSON string and compare them ```javascript let x = [1, 2, 3]; if (JSON.stringify(x) === JSON.stringify([1, 2, 3])) { } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0342.md # E0342: using equality or inequality operators against an arrow function will always produce the same result Using equality or inequality operators against an arrow function will always yield the same result (false or true), e.g. In the code below, the equality operator is used by mistake against an arrow function. ```javascript class Car { constructor(acceleration, speed) { this.acceleration = acceleration; this.speed = speed; } hitTheGas(acceleration) { this.acceleration += acceleration; } }; let vehicle = new Car(0, 0); let acceleration = (force) => { vehicle.hitTheGas(10 * force); }; let sport_mode = true; if (sport_mode) { acceleration == (force) => { vehicle.hitTheGas(15 * force); }; } ``` To fix this warning, we need to replace the equality operator with the assigment operator. ```javascript class Car { constructor(acceleration, speed) { this.acceleration = acceleration; this.speed = speed; } hitTheGas(acceleration) { this.acceleration += acceleration; } }; let vehicle = new Car(0, 0); let acceleration = (force) => { vehicle.hitTheGas(10 * force); }; let sport_mode = true; if (sport_mode) { acceleration = (force) => { vehicle.hitTheGas(15 * force); }; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0343.md # E0343: using '==' against a class literal always returns 'false' ```config-for-examples { "globals": { "__DEBUG__": true } } ``` In JavaScript, you can create a class in an expression. The class is a brand new class, so comparing the class using `==`, `===`, `!=`, or `!==` will always give the same result (`false` or `true`): ```javascript let Logger; if (__DEBUG__) { Logger = class { log(msg) { console.log(msg); } }; } else { Logger == class { log(msg) { } }; } ``` To fix this error, write `=` instead of `==`: ```javascript let Logger; if (__DEBUG__) { Logger = class { log(msg) { console.log(msg); } }; } else { Logger = class { log(msg) { } }; } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0344.md # E0344: using '===' or '!==' against an empty array literal always produces the same result Using the strict equality operator against an empty array literal will always return 'false', and using the strict inequality operator will always return 'true'. e.g. the conditions below will always be 'false' and 'true' respectively, no matter what value 'x' holds. ```javascript let x = []; // the expression inside the if statement is always 'false' if (x === []) { } // the expression inside the if statement is always 'true' if (x !== []) { } ``` To fix this particular example, we could compare the length of the array ```javascript let x = []; if (x.length === 0) { } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0345.md # E0345: using equality or inequality operators against an object literal always produces the same result Using equality or inequality operators against any object literal will always yield false or true respectively, e.g. ```javascript const cat = { name: 'Morris', sex: 'Male', }; // the expression inside the if statement is always 'false' if (cat === { name: 'Morris', sex: 'Male' }) { } // the expression inside the if statement is always 'true' if (cat !== { name: 'Morris', sex: 'Male' }) { } ``` To fix this particular example, we could compare the properties manually ```javascript const cat = { name: 'Morris', sex: 'Male', }; if (cat.name === 'Morris' && cat.sex === 'Male') { } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0346.md # E0346: using '==' against a regular expression literal always returns 'false' In JavaScript, writing `/regularexpression/` creates a new `RegExp` object. so comparing a regular expression literal using `==`, `===`, `!=`, or `!==` will always give the same result (`false` or `true`): ```javascript function isCapitalized(s) { return /^[A-Z]/ == s; } ``` To fix this issue, if you intended to check if a string matches a regular expression, call the `RegExp#test` method instead of writing `==`: ```javascript function isCapitalized(s) { return /^[A-Z]/.test(s); } ``` Introduced in quick-lint-js version 2.10.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0347.md # E0347: duplicated case clause in switch statement It's common to copy-paste case clauses when writing switch statements, but this could lead to duplicated expressions in the switch cases by accident. For example, in the code below, there's a duplicated case with the expression '*' when '+' was clearly intended. ```javascript function compute(operator, firstNumber, secondNumber) { switch (operator) { case '*': return firstNumber * secondNumber; case '-': return firstNumber - secondNumber; case '*': return firstNumber + secondNumber; } } ``` To fix this warning, we need to replace the expression '*' in the last switch case with the expression '+' ```javascript function compute(operator, firstNumber, secondNumber) { switch (operator) { case '*': return firstNumber * secondNumber; case '-': return firstNumber - secondNumber; case '+': return firstNumber + secondNumber; } } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0348.md # E0348: unexpected '?' in type; use '| void' to make an optional type Using a question mark as a prefix or suffix to make parameter types optional is invalid. Instead add a second 'void' type to the parameter. ```typescript import * as fs from 'fs'; const file = "./out.txt"; const data = "test"; fs.promises.writeFile(file, data) .then((err: Error?) => { if (err) throw err; }); ``` To fix this warning, we need to replace the '?' suffix or prefix with the expression '| void' ```typescript import * as fs from 'fs'; const file = "./out.txt"; const data = "test"; fs.promises.writeFile(file, data) .then((err: Error | void) => { if (err) throw err; }); ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0349.md # E0349: function parameter cannot be parenthesized Using parenthesis around the function parameter is invalid. ```typescript let g = ((x)) => { }; let f = function ((x)) { }; ``` To fix this error, remove the parenthesis. ```typescript let g = (x) => { }; let f = function (x) { }; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0358.md # E0358: 'declare' should not be written inside a 'declare namespace' Inside `declare namespace`, declarations (functions, classes, etc.) are automatically `declare`. It is a syntax error to explicitly write `declare` on these declarations: ```typescript declare namespace jQuery { declare function get(url); } ``` To fix this error, remove the `declare` keyword: ```typescript declare namespace jQuery { function get(url); } ``` This bug is common in `.d.ts` files because many projects use [`skipLibCheck` in `tsconfig.json`](https://www.typescriptlang.org/tsconfig#skipLibCheck) which disables TypeScript's checking of `.d.ts` files. We recommend fixing your `.d.ts` files as described above. If you disagree, please [discuss this with the quick-lint-js maintainers](https://github.com/quick-lint/quick-lint-js/issues/1142). --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0369.md # E0369: nullish coalescing operator does nothing when left operand is never null When left operand is never null (such as comparisons and string literals), the expression will always resolve to the left operand value ```typescript let g = "hello" ?? "world"; let f = 4 == 5 ?? true; ``` To fix this warning, remove the nullish coalescing operaror (??) and the right operand. ```typescript let g = "hello"; let f = 4 == 5; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0373.md # E0373: unexpected whitespace between '!' and '=='; '!' here treated as the TypeScript non-null assertion operator While `x! == y` is legal TypeScript for a non-null assertion, it may be a typo for a strict inequality, as in `x !== y`: ```typescript let x = 17; let y = 38; if (x! == y) { alert('Not equal!'); } ``` To fix the warning, replace `! ==` with ` !==`: ```typescript let x = 17; let y = 38; if (x !== y) { alert("Not equal!"); } ``` To suppress this warning, add parentheses around the non-null assertion: ```typescript let x = 17; let y = 38; if ((x!) == y) { alert("Not equal!"); } ``` See also: E0374 --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0374.md # E0374: unexpected whitespace between '!' and '==' `x! == y` is a typo for a strict inequality, as in `x !== y`: ```javascript let x = 17; let y = 38; if (x! == y) { alert('Not equal!'); } ``` To fix the warning, replace `! ==` with ` !==`: ```javascript let x = 17; let y = 38; if (x !== y) { alert("Not equal!"); } ``` See also: E0373 --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0376.md # E0376: JSX prop is missing an expression Every attribute in JSX with a prop requires an expression: ```javascript-jsx function Header({columns}) { return (<>
    Name
    ); } ``` To fix the mistake, add a valid expression to the prop: ```javascript-jsx function Header({columns}) { return (<>
    Name
    ); } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0379.md # E0379: optional parameter cannot be followed by a required parameter Optional parameters need to be placed after the required ones. ```typescript function f(param1?: number, param2: number) { if (param1) { return param1 } return param2; } ``` To fix this warning, we need to place the required parameter(s) first, followed by the optional parameters ```typescript function f(param2: number, param1?: number) { if (param1) { return param1 } return param2; } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0381.md # E0381: Typescript does not allow keywords to contain escape sequence The following code is legal in JavaScript but is illegal in TypeScript ```typescript class C { \u{63}onstructor() {} // equivalent to: constructor() {} } ``` To fix this error, remove the escape sequence in the keyword. ```typescript class C { constructor() {} // equivalent to: constructor() {} } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0383.md # E0383: variable assignment to self is no-op ```config-for-examples { "globals": { "previous": true, "switchToPage": true } } ``` The following contains a no-op (`next = next;`): ```javascript let next = 0; if (previous !== null) { next = next; } switchToPage(next); ``` To fix this, change the assignment so it's not assigning a variable to itself: ```javascript let next = 0; if (previous !== null) { next = previous; } switchToPage(next); ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0427.md # E0427: missing 'break;' or '// fallthrough' comment between statement and 'case' Switch Cases in javascript fallthrough to the next case if the `break` statement is not added at the end of the case. Since there is no explicit way of communication whether the fallthrough is intentional or not, it is recommended to use a comment indicating fallthrough. ```javascript function test (c) { switch (c) { case 1: console.log('case 1'); default: console.log('default'); } } ``` To fix this error, place a comment at the end of `case 1` indicating fallthrough ```javascript function test (c) { switch (c) { case 1: console.log('case 1'); //fallthrough default: console.log('default'); } } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0450.md # E0450: misleading use of ',' operator in index Using comma operator within an indexing operation is misleading, as it can be confused with a new array definition, or with access to multiple elements of the container. For example: ```javascript let matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; let topLeft = matrix[0, 0]; ``` Here, the value of `topLeft` will be equal to `matrix[0] = [1, 2, 3]`. If the intention is to find the value at the top-left corner of `matrix`, the correct syntax would be: ```javascript let matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; let topLeft = matrix[0][0]; // topLeft = 1 ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0451.md # E0451: misleading use of ',' operator in conditional statement Using comma operator within a conditional statement of a control block (`if`, `for`, `while`, `switch`) is misleading, because only the last expression will be used to evaluate the condition. For example: ```javascript let N = 10; for (let i = 0, j = N - 1; i < j, j >= 0; ++i, --j) { console.log(i, j); } ``` Here, the statement `i < j, j >= 0` will be evaluated as `j >= 0`, disregarding the first part (`i < j`) of the statement. In order to have both parts evaluated, a logical operator should be used instead of the comma operator. ```javascript let N = 10; for (let i = 0, j = N - 1; i < j && j >= 0; ++i, --j) { console.log(i, j); } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0452.md # E0452: empty parenthesis after control statement Leaving parenthesis empty after control statements (`if`, `while`, `switch`, `with`) is a syntax error. ```javascript while () { console.log("Oops!..") } ``` If the intention here was to create an infinite loop, the implementation would be this: ```javascript while (true) { console.log("Now, that's an infinite loop"); } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0458.md # E0458: typeof result is of type string and so will never equal undefined; use 'undefined' instead The `typeof` operator will always return a string, so comparing to undefined will always yield false. ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof)) ```javascript let x = undefined; if (typeof x === undefined) { // this will never run! alert("x is undefined!"); } ``` Instead, compare against the string `"undefined"`: ```javascript let x = undefined; if (typeof x === "undefined") { // this will run now :) alert("x is undefined!"); } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0707.md # E0707: classes cannot be named 'await' in async function This error has been renamed to E0069. Introduced in quick-lint-js version 2.5.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0708.md # E0708: unexpected '...'; expected expression The spread ('...') operator must precede an expression: ```javascript const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const arr3 = [...arr1, ...]; ``` To fix this error, insert a valid expression after the operator: ```javascript const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const arr3 = [...arr1, ...arr2]; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0709.md # E0709: expected variable name after '...' The spread operator ('...') must precede a variable name. ```javascript const numbers = () => { return [1, 2, 3, 4] }; const [numberOne, numberTwo, ...] = numbers(); ``` To fix this mistake, place the identifier after '...': ```javascript const numbers = () => { return [1, 2, 3, 4] }; const [numberOne, numberTwo, ...rest] = numbers(); ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0710.md # E0710: '^' is the XOR operator; to exponentiate, use '**' instead The Exclusive OR operator ^ can sometimes be mistaken for the exponentiation operator **. ```javascript let x = 2 ^ 8 ``` If the intention was to exponentiate, the operator ^ should be replaced with ** ```javascript let x = 2 ** 8 ``` Alternatively, if the intention was to use the ^ operator for XOR operation, The resulting literal could be used directly (2 ^ 8 = 10) ```javascript let x = 10 ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0711.md # E0711: missing expression in placeholder within template literal Everytime you use `${}` within a template literal, which is a string defined with backticks, such as this one below inside `console.log`, you should specify an expression inside its curly braces. ```javascript console.log(`My name is ${}`); ``` To fix this error, write an expression between `${` and `}`: ```javascript const yourName = "Ryan"; console.log(`My name is ${yourName}`); ``` If your goals were to have the placeholder literally in your string, consider escaping it using a backslash before the placeholder: ```javascript console.log(`\${}`); ``` Or just use double-quoted string (`""`): ```javascript console.log("${}"); ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0712.md # E0712: missing ',' between array elements This error occurs when there is a missing comma (',') between elements in an array declaration or initialization. In JavaScript, commas are used to separate individual elements within an array, and the absence of a comma will lead to a syntax error. ```javascript let myArray = [1 2 3]; ``` To fix this error, you need to add a comma between each element within the array declaration or initialization ```javascript let myArray = [1, 2, 3]; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0713.md # E0713: getters and setters cannot be generators Use of the '*' character, defining generator functions, is not allowed on getters or setters. Getters and setters are synchronous operations and do not support the generator functionality. ```javascript class C { constructor() { this._value = 0; } get *value() { return this._value; } set *value(newValue) { this._value = newValue; } } ``` To fix this error define a getter or setter, using regular function syntax. ```javascript class C { constructor() { this._value = 0; } get value() { return this._value; } set value(newValue) { this._value = newValue; } } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0714.md # E0714: 'async' keyword is not allowed on getters or setters Use of 'async' keyword, defining asynchronous functions, is not allowed on getters or setters. Getters and setters are synchronous operations and do not support the asynchronous functionality. ```javascript class C { constructor() { this._value = 0; } async get value() { return this._value; } async set value(newValue) { this._value = newValue; } } ``` To fix this error simply remove 'async' keyword from getters and setters, so they can function properly as synchronous operations. ```javascript class C { constructor() { this._value = 0; } get value() { return this._value; } set value(newValue) { this._value = newValue; } } ``` However, if you require asynchronous behavior within getters or setters, you can achieve this by implementing separate asynchronous methods. ```javascript class C { constructor() { this._value = 0; } async getValueAsync() { return await fetch(this._value); } async setValueAsync(newValue) { this._value = await fetch(newValue); } } ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0715.md # E0715: cannot use multiple `export default` statements in one module Modules in JavaScript can use two types of exports: default export and named export. While a module can use multiple named exports, it can only use a single default export. ```javascript export default function foo() { console.log("foo"); } export default function bar() { console.log("bar"); } ``` If you want to export several values from a module, use named exports. ```javascript function foo(x) { console.log("foo"); } function bar(x) { console.log("bar"); } export { foo, bar }; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0716.md # E0716: unintuitive operator precedence when using & and << or >> ```config-for-examples { "globals": { "another_variable": true } } ``` JavaScript's operator precedence can cause confusing situations and bugs when it comes to bitshifting with a bitwise and. ```js let a_bitwise_variable = another_variable & 0x1 << 0x2 ``` The code above looks like it evaluates `another_variable & 0x1` first, but it instead evaluates `0x1 << 0x2` first. If this is intended behavior, it may be easier to read if you write parentheses: ```js another_variable & (0x1 << 0x2) ``` Otherwise, to get the order of operations correct, add parentheses around the operands of `&`: ```js (another_variable & 0x1) << 0x2 ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0717.md # E0717: namespace alias cannot use 'import type' The error message "namespace alias cannot use 'import type'" occurs when trying to use the 'import type' syntax with an alias. ```typescript import type A = ns; ``` To fix this error, you need to use the regular 'import' syntax instead of 'import type' when using an alias. ```typescript import A = ns; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0718.md # E0718: using a '.' after a '?.' might fail, since '?.' might return 'undefined' This diagnostic has been removed in quick-lint-js version 3.2.0. --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0719.md # E0719: TypeScript namespace aliases are not allowed in JavaScript ```config-for-examples { "globals": { "goog": true } } ``` TypeScript supports aliasing namespaces and namespace members using `import`. It is a syntax error to write such an alias in JavaScript code: ```javascript import Chart = goog.Chart; ``` To fix this error, use `const` instead of `import`: ```javascript const Chart = goog.Chart; ``` ```javascript const { Chart } = goog; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/errors/E0720.md # E0720: function 'let' call may be confused for destructuring; remove parentheses to declare a variable ```config-for-examples { "globals": { "let": true, "first": true } } ``` In JavaScript, variables can be named `let` and interpreted as a function call if it is followed by parentheses. This code calls function `let` instead of destructuring an object: ```javascript const words = {first: "hello", second: "world"}; let ({first} = words); ``` If you want to declare a variable, remove the parentheses: ```javascript const words = {first: "hello", second: "world"}; let {first} = words; ``` --- # Source: https://github.com/quick-lint/quick-lint-js/blob/master/docs/profiling.md # Profiling quick-lint-js * [Speed](#run-time-speed) * [Benchmarks](#benchmarks) * [Vector profiler](#vector-profiler) * [Parse tracing](#parse-tracing) * [Build size](#build-size) * [Build speed](#build-speed) ## Run-time speed ### Benchmarks [quick-lint-js has benchmarks](../benchmark/README.txt) for various things, including parsing, location tracking, and LSP. TODO: Write a script to compare two builds. You can profile a benchmark using tools like `perf` (Linux) or Instruments (macOS) or any other tool. Run a benchmark for a while to allow enough samples: $ ninja -C build quick-lint-js-benchmark-parse $ QLJS_PARSE_BENCHMARK_SOURCE_FILE=~/tmp/jquery-3.5.1.js \ perf record \ ./build/benchmark/quick-lint-js-benchmark-parse \ --benchmark_min_time=2 \ --benchmark_filter=benchmark_parse_file $ perf report ### Vector profiler Collect and dump statistics about our usage of vectors (resizable arrays). Current statistics: * Max sizes: How big does a vector get? This helps decide good initial reservations. * Capacity changes: How often do vector items get copied due to `push_back`/`emplace_back`? This helps decide whether reservations are working, and help tune vector growth strategies. 1. Set the `QUICK_LINT_JS_FEATURE_VECTOR_PROFILING` CMake variable to `ON`. 2. Build `quick-lint-js` (CLI). 3. When running the CLI, set the `QLJS_DUMP_VECTORS` environment variable to `1`. Example output: Max sizes for parse_arrow_function_expression_remainder: 0 ( 0%) 1 (ALL) * Max sizes for parse_expression_remainder call children: 0 ( 0%) 1 (40%) ****** 2 (53%) ******** 3 ( 7%) * Max sizes for parse_expression_remainder children: 0 ( 0%) 1 (ALL) *************************************************** Max sizes for parse_object_literal entries: 0 ( 0%) 1 ( 0%) 2 (ALL) * Max sizes for parse_template children: 0 ( 0%) 1 (50%) * 2 ( 0%) 3 ( 0%) 4 (50%) * vector capacity changes: (C=copied; z=initial alloc; -=used internal capacity) parse_arrow_function_expression_remainder: 0C 1z 0_ |zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz| parse_expression_remainder call children: 0C 15z 10_ |zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz___________________________| parse_expression_remainder children: 0C 59z 0_ |zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz| parse_object_literal entries: 0C 1z 1_ |zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz_________________________________| parse_template children: 0C 2z 3_ |zzzzzzzzzzzzzzzzzzzzzzzzzz________________________________________| ### Parse tracing quick-lint-js' Visual Studio Code extension can [log parse times](../plugin/vscode/PERFORMANCE-TRACING.md). ## Build speed [Clang has a time profiler](https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/) which helps you determine what might be slow to parse or code-gen. Find files which are slow compile: Generate a gantt chart from Ninja (build system) timings with [strager's gnuplot script published November 13, 2020](https://strager.net/microblog.html). ## Build size Before and after making an optimization, see big quick-lint-js is: $ ninja -C build quick-lint-js && strip -o build/quick-lint-js{.stripped,} && ls -lh build/quick-lint-js* [Bloaty profiles executable sizes](https://github.com/google/bloaty). Run it on a `CMAKE_BUILD_TYPE=Release` build of quick-lint-js: $ bloaty -d symbols -n 300 build/quick-lint-js Track quick-lint-js [build sizes over time](../tools/build-sizes/index.html).