Skip to content

Commit c74f105

Browse files
committed
Add allowed values for list options
1 parent 28ea606 commit c74f105

File tree

2 files changed

+63
-77
lines changed

2 files changed

+63
-77
lines changed

packages/tsconfig-reference/copy/en/options/lib.md

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,3 @@ In TypeScript 4.5, lib files can be overriden by npm modules, find out more [in
3232
| `DOM` | [DOM](https://developer.mozilla.org/docs/Glossary/DOM) definitions - `window`, `document`, etc. |
3333
| `WebWorker` | APIs available in [WebWorker](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Using_web_workers) contexts |
3434
| `ScriptHost` | APIs for the [Windows Script Hosting System](https://wikipedia.org/wiki/Windows_Script_Host) |
35-
36-
### Individual library components
37-
38-
| Name |
39-
| ------------------------- |
40-
| `DOM.Iterable` |
41-
| `ES2015.Core` |
42-
| `ES2015.Collection` |
43-
| `ES2015.Generator` |
44-
| `ES2015.Iterable` |
45-
| `ES2015.Promise` |
46-
| `ES2015.Proxy` |
47-
| `ES2015.Reflect` |
48-
| `ES2015.Symbol` |
49-
| `ES2015.Symbol.WellKnown` |
50-
| `ES2016.Array.Include` |
51-
| `ES2017.object` |
52-
| `ES2017.Intl` |
53-
| `ES2017.SharedMemory` |
54-
| `ES2017.String` |
55-
| `ES2017.TypedArrays` |
56-
| `ES2018.Intl` |
57-
| `ES2018.Promise` |
58-
| `ES2018.RegExp` |
59-
| `ES2019.Array` |
60-
| `ES2019.Object` |
61-
| `ES2019.String` |
62-
| `ES2019.Symbol` |
63-
| `ES2020.String` |
64-
| `ES2020.Symbol.wellknown` |
65-
| `ES2021.Promise` |
66-
| `ES2021.String` |
67-
| `ES2021.Weakref` |
68-
| `ESNext.AsyncIterable` |
69-
| `ESNext.Array` |
70-
| `ESNext.Intl` |
71-
| `ESNext.Symbol` |
72-
73-
This list may be out of date, you can see the full list in the [TypeScript source code](https://github.com/microsoft/TypeScript/tree/main/lib).

packages/tsconfig-reference/scripts/tsconfigRules.ts

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@ import * as remark from "remark";
33
import * as remarkHTML from "remark-html";
44
import * as ts from "typescript";
55

6+
interface CommandLineOption {
7+
name: string;
8+
type:
9+
| "string"
10+
| "number"
11+
| "boolean"
12+
| "object"
13+
| "list"
14+
| Map<string, number | string>;
15+
defaultValueDescription?: string | number | boolean | ts.DiagnosticMessage;
16+
element: CommandLineOption;
17+
}
18+
19+
declare module "typescript" {
20+
const optionDeclarations: CommandLineOption[];
21+
const optionsForWatch: CommandLineOption[];
22+
}
23+
624
/**
725
* Changes to these rules should be reflected in the following files:
826
* https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/tsconfig.json
@@ -173,26 +191,17 @@ function trueIf(name: string) {
173191
];
174192
}
175193

176-
// Number/boolean options without explicit default are 0/false
177-
const defaultDefaults = { number: "0", boolean: "false" };
178194
export const defaultsForOptions = {
179195
...Object.fromEntries(
180-
ts.optionDeclarations
181-
.filter(
182-
(option) =>
183-
("defaultValueDescription" in option &&
184-
option.defaultValueDescription !== "n/a") ||
185-
option.type in defaultDefaults
186-
)
187-
.map((option) => [
188-
option.name,
189-
!("defaultValueDescription" in option) ||
190-
option.defaultValueDescription === "n/a"
191-
? defaultDefaults[option.type]
192-
: typeof option.defaultValueDescription === "string"
193-
? option.defaultValueDescription
194-
: option.defaultValueDescription.message,
195-
])
196+
ts.optionDeclarations.map((option) => [
197+
option.name,
198+
typeof option.defaultValueDescription === "object"
199+
? option.defaultValueDescription.message
200+
: formatDefaultValue(
201+
option.defaultValueDescription,
202+
option.type === "list" ? option.element.type : option.type
203+
),
204+
])
196205
),
197206
allowSyntheticDefaultImports: [
198207
"`true` if [`module`](#module) is `system`, or [`esModuleInterop`](#esModuleInterop) and [`module`](#module) is not `es6`/`es2015` or `esnext`,",
@@ -222,7 +231,7 @@ export const defaultsForOptions = {
222231
newLine: "Platform specific.",
223232
noImplicitAny: trueIf("strict"),
224233
noImplicitThis: trueIf("strict"),
225-
preserveConstEnums: "false",
234+
preserveConstEnums: trueIf("isolatedModules"),
226235
reactNamespace: "React",
227236
rootDir: "Computed from the list of input files.",
228237
rootDirs: "Computed from the list of input files.",
@@ -238,31 +247,47 @@ export const defaultsForOptions = {
238247
],
239248
};
240249

250+
function formatDefaultValue(
251+
defaultValue: CommandLineOption["defaultValueDescription"],
252+
type: CommandLineOption["type"]
253+
) {
254+
if (defaultValue === undefined || typeof type !== "object")
255+
return defaultValue;
256+
// e.g. ScriptTarget.ES2015 -> "es6/es2015"
257+
const synonyms = [...type]
258+
.filter(([, value]) => value === defaultValue)
259+
.map(([name]) => name);
260+
return synonyms.length > 1
261+
? synonyms.map((name) => `\`${name}\``).join("/")
262+
: synonyms[0];
263+
}
264+
241265
export const allowedValues = {
242266
...Object.fromEntries(
243-
[...ts.optionDeclarations, ...ts.optionsForWatch]
244-
.filter((option) => typeof option.type === "object")
245-
.map((option) => {
246-
// Group and format synonyms: `es6`/`es2015`
247-
const byValue: { [value: number]: string[] } = {};
248-
for (const [name, value] of option.type instanceof Map
249-
? option.type.entries()
250-
: Object.entries(option.type)) {
251-
(byValue[value] ||= []).push(name);
252-
}
253-
return [
254-
option.name,
255-
Object.values(byValue).map((synonyms) =>
256-
synonyms.length > 1
257-
? synonyms.map((name) => `\`${name}\``).join("/")
258-
: synonyms[0]
259-
),
260-
];
261-
})
267+
[...ts.optionDeclarations, ...ts.optionsForWatch].map((option) => [
268+
option.name,
269+
formatAllowedValues(
270+
option.type === "list" ? option.element.type : option.type
271+
),
272+
])
262273
),
263274
jsxFactory: ["Any identifier or dotted identifier."],
264275
};
265276

277+
function formatAllowedValues(type: CommandLineOption["type"]) {
278+
if (typeof type !== "object") return;
279+
// Group and format synonyms: `es6`/`es2015`
280+
const inverted: { [value: string]: string[] } = {};
281+
for (const [name, value] of type) {
282+
(inverted[value] ||= []).push(name);
283+
}
284+
return Object.values(inverted).map((synonyms) =>
285+
synonyms.length > 1
286+
? synonyms.map((name) => `\`${name}\``).join("/")
287+
: synonyms[0]
288+
);
289+
}
290+
266291
export const releaseToConfigsMap: { [key: string]: AnOption[] } = {
267292
"4.5": ["preserveValueImports"],
268293
"4.4": ["exactOptionalPropertyTypes", "useUnknownInCatchVariables"],

0 commit comments

Comments
 (0)