-
Notifications
You must be signed in to change notification settings - Fork 532
Expand file tree
/
Copy pathtsconfig.json
More file actions
60 lines (57 loc) · 3.84 KB
/
tsconfig.json
File metadata and controls
60 lines (57 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
"include": ["src/*.ts", "src/**/*.ts"],
"compilerOptions": {
"rootDir": "src/",
"target": "es6",
// What we would IDEALLY like to do is compile against type declarations corresponding to
// precisely what is available in BOTH the "Widely Available" Baseline
// (https://web.dev/baseline) AND the latest Node.js LTS, since jsdiff supports both.
// Alas, there is no way to do this. As of configuring the settings below (7th
// April 2026)...
// 1. there is simply no way to tell TypeScript to use the intersection of two sets of
// global type declarations (i.e. to only let us use stuff supported by both
// environments). At best, we can minimise how many global type declarations we include
// by keeping the "lib" and "types" arrays below minimal, and ideally avoiding including
// anything in them that is either browser-specific or Node-specific.
// 2. jsdiff actually uses some stuff that is both "Widely Available" and available in Node,
// but not part of *any* ECMAScript spec. These include `TextDecoder`, which has its own
// dedicated spec, and `setTimeout`, which is (weirdly!) part of the HTML standard, not
// the ECMAScript spec (although Node has its own, identical-ish implementation).
// Consequently setting `"lib": ["esnext"]` will not suffice to let jsdiff compile; to
// get to a tsconfig that actually works, we MUST include "dom" in the "lib" array
// and/or use the @types/node type declaration module by including "node" in the
// "types" array.
// Obviously, both available solutions to point 2 above are unsatisfactory, due to point 1.
// If we include "dom" in the "lib" array, then if we use browser-specific features in our
// TypeScript code (that won't work in Node), TypeScript will not warn us about it at
// compilation time. If we instead use `types: ["node"]`, the converse problem will exist.
//
// Faced with two unsatisfactory options, we reluctantly choose one. But it means we
// absolutely cannot rely on TypeScript to catch if we use a global that isn't actually
// available in all our supported environments, and so must rely on tests and vigilance.
"lib": [
"es2023", "dom"
],
"types": [],
"declaration": true,
"skipLibCheck": true,
// Options below enabled per recommendation at
// https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html#im-writing-a-library
"strict": true,
"declarationMap": true,
// The same docs page recommends setting
// "verbatimModuleSyntax": true,
// but this totally breaks the CJS build and a footnote observes that "Any configuration
// that produces both an ESM and a CJS output from the same source file is fundamentally
// incompatible with" this setting. I don't really know WTF the authors of those docs were
// thinking, because the recommendation to turn this setting on is from the section
// specifically for "a library author" who wants to ensure their code works "under all
// possible library consumer compilation settings" - i.e. a person who is essentially 100%
// guaranteed to be running both an ESM and CJS build. So how can the recommendation to
// turn this setting on possibly be even remotely sane? Beats me. ¯\_(ツ)_/¯
// I've done the best I can by using the @typescript-eslint/consistent-type-imports and
// @typescript-eslint/consistent-type-exports ESLint rules to enforce SOME of what this
// setting would have enforced, though I dunno if I'm enforcing the bits that motivated the
// recommendation to turn it on.
}
}