eslint-plugin-ts-type-forge 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -8
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +34 -30
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +15 -0
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rule-types.mjs +2 -1
- package/dist/rule-types.mjs.map +1 -1
- package/dist/rules/ast-utils.mjs +224 -103
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/constants.mjs +14 -11
- package/dist/rules/constants.mjs.map +1 -1
- package/dist/rules/import-style.mjs +31 -26
- package/dist/rules/import-style.mjs.map +1 -1
- package/dist/rules/import-utils.mjs +49 -29
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/index.mjs +2 -2
- package/dist/rules/index.mjs.map +1 -1
- package/dist/rules/no-side-effect-import.d.mts +19 -0
- package/dist/rules/no-side-effect-import.d.mts.map +1 -0
- package/dist/rules/no-side-effect-import.mjs +55 -0
- package/dist/rules/no-side-effect-import.mjs.map +1 -0
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs +93 -73
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs.map +1 -1
- package/dist/rules/prefer-canonical-mutable-record.mjs +88 -75
- package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-readonly-or-mutable-record.mjs +41 -45
- package/dist/rules/prefer-readonly-or-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs +48 -46
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs.map +1 -1
- package/dist/rules/rewrite-rule-utils.mjs +31 -28
- package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
- package/dist/rules/rules.d.mts +1 -0
- package/dist/rules/rules.d.mts.map +1 -1
- package/dist/rules/rules.mjs +8 -9
- package/dist/rules/rules.mjs.map +1 -1
- package/dist/rules/std-type-rule-utils.mjs +47 -30
- package/dist/rules/std-type-rule-utils.mjs.map +1 -1
- package/dist/types.mjs +2 -2
- package/dist/types.mjs.map +1 -1
- package/package.json +6 -7
- package/src/plugin.mts +1 -0
- package/src/rule-types.mts +16 -0
- package/src/rules/no-side-effect-import.mts +73 -0
- package/src/rules/no-side-effect-import.test.mts +83 -0
- package/src/rules/rules.mts +2 -0
package/README.md
CHANGED
|
@@ -72,12 +72,13 @@ export default [
|
|
|
72
72
|
|
|
73
73
|
## Rules
|
|
74
74
|
|
|
75
|
-
| Rule | Fix | Description
|
|
76
|
-
| :------------------------------------------ | :--------- |
|
|
77
|
-
| `prefer-canonical-length-constrained-tuple` | autofix | Replace hand-rolled uniform tuple spellings with the canonical ts-type-forge tuple type.
|
|
78
|
-
| `prefer-canonical-mutable-record` | autofix | Replace `Mutable<Record<K, V>>` with the canonical `MutableRecord<K, V>`.
|
|
79
|
-
| `prefer-strict-or-relaxed-utility-type` | suggestion | Replace `Exclude` / `Extract` / `Omit` / `Pick` with the `Strict*` or `Relaxed*` variant.
|
|
80
|
-
| `prefer-readonly-or-mutable-record` | suggestion | Replace `Record` with `ReadonlyRecord` or `MutableRecord`.
|
|
75
|
+
| Rule | Fix | Description |
|
|
76
|
+
| :------------------------------------------ | :--------- | :--------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| `prefer-canonical-length-constrained-tuple` | autofix | Replace hand-rolled uniform tuple spellings with the canonical ts-type-forge tuple type. |
|
|
78
|
+
| `prefer-canonical-mutable-record` | autofix | Replace `Mutable<Record<K, V>>` with the canonical `MutableRecord<K, V>`. |
|
|
79
|
+
| `prefer-strict-or-relaxed-utility-type` | suggestion | Replace `Exclude` / `Extract` / `Omit` / `Pick` with the `Strict*` or `Relaxed*` variant. |
|
|
80
|
+
| `prefer-readonly-or-mutable-record` | suggestion | Replace `Record` with `ReadonlyRecord` or `MutableRecord`. |
|
|
81
|
+
| `no-side-effect-import` | autofix | Remove a side-effect-only `import 'ts-type-forge';`, which binds no name and has no runtime entry point to resolve to. |
|
|
81
82
|
|
|
82
83
|
### `prefer-canonical-length-constrained-tuple`
|
|
83
84
|
|
|
@@ -208,10 +209,32 @@ type Counters = MutableRecord<string, number>;
|
|
|
208
209
|
these rules report **suggestions** rather than an autofix. Editors offer both
|
|
209
210
|
replacements; `--fix` changes nothing.
|
|
210
211
|
|
|
212
|
+
### `no-side-effect-import`
|
|
213
|
+
|
|
214
|
+
`ts-type-forge` ships declarations and nothing else — its `exports` map offers
|
|
215
|
+
no runtime condition — so `import 'ts-type-forge';` binds no name _and_ fails to
|
|
216
|
+
resolve the moment the module graph is loaded. A side-effect import is the one
|
|
217
|
+
kind TypeScript never elides, so the line survives compilation: a runtime error
|
|
218
|
+
sitting in a file that type-checks.
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
// ❌
|
|
222
|
+
import 'ts-type-forge';
|
|
223
|
+
|
|
224
|
+
// ✅ types are reached by name
|
|
225
|
+
import { type NonEmptyArray } from 'ts-type-forge';
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The fix deletes the import along with its line. Only the bare specifier matches:
|
|
229
|
+
`ts-type-forge/global` — the ambient globals, usually brought in through
|
|
230
|
+
`compilerOptions.types` or `/// <reference types="ts-type-forge/global" />` — is
|
|
231
|
+
left alone, as is every other module.
|
|
232
|
+
|
|
211
233
|
## Options
|
|
212
234
|
|
|
213
|
-
`importStyle` is accepted by every rule; `maxLength` only
|
|
214
|
-
`prefer-canonical-length-constrained-tuple`.
|
|
235
|
+
`importStyle` is accepted by every rule that rewrites a type; `maxLength` only
|
|
236
|
+
by `prefer-canonical-length-constrained-tuple`. `no-side-effect-import` takes no
|
|
237
|
+
options.
|
|
215
238
|
|
|
216
239
|
| Option | Type | Default | Description |
|
|
217
240
|
| :------------ | :-------------------- | :-------- | :------------------------------------------------------------------ |
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { eslintPluginTsTypeForge } from './plugin.mjs';
|
|
2
|
-
export { tsTypeForgeRules } from './rules/
|
|
3
|
-
//# sourceMappingURL=index.mjs.map
|
|
2
|
+
export { tsTypeForgeRules } from './rules/index.mjs';
|
|
3
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAKvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/plugin.d.mts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const eslintPluginTsTypeForge: {
|
|
|
4
4
|
readonly name: 'eslint-plugin-ts-type-forge';
|
|
5
5
|
};
|
|
6
6
|
readonly rules: {
|
|
7
|
+
readonly 'no-side-effect-import': import("@typescript-eslint/utils/ts-eslint").RuleModule<"removeSideEffectImport", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
8
|
readonly 'prefer-canonical-length-constrained-tuple': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useCanonicalTuple", readonly [(Readonly<{
|
|
8
9
|
importStyle?: 'global' | 'named';
|
|
9
10
|
maxLength?: number;
|
|
@@ -26,6 +27,7 @@ export declare const eslintPluginTsTypeForge: {
|
|
|
26
27
|
readonly 'ts-type-forge': ESLintPlugin;
|
|
27
28
|
};
|
|
28
29
|
readonly rules: {
|
|
30
|
+
readonly 'ts-type-forge/no-side-effect-import': 'error';
|
|
29
31
|
readonly 'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error';
|
|
30
32
|
readonly 'ts-type-forge/prefer-canonical-mutable-record': 'error';
|
|
31
33
|
readonly 'ts-type-forge/prefer-readonly-or-mutable-record': 'error';
|
package/dist/plugin.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAkCvE,eAAO,MAAM,uBAAuB;;iBAEhC,IAAI,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;QAInC,oDAAoD;iBACpD,WAAW;2BAtBP,2BAA2B;;yBAQ3B,eAAe,EAAI,YAAY;;;gEAlBE,OAAO;oFACa,OAAO;0EACjB,OAAO;4EACL,OAAO;gFACH,OAAO;;;;CA8B/B,CAAC"}
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
import { tsTypeForgeRules } from './rules/
|
|
1
|
+
import { tsTypeForgeRules } from './rules/index.mjs';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
2
7
|
|
|
3
8
|
const recommendedRules = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
'ts-type-forge/no-side-effect-import': 'error',
|
|
10
|
+
'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error',
|
|
11
|
+
'ts-type-forge/prefer-canonical-mutable-record': 'error',
|
|
12
|
+
'ts-type-forge/prefer-readonly-or-mutable-record': 'error',
|
|
13
|
+
'ts-type-forge/prefer-strict-or-relaxed-utility-type': 'error',
|
|
8
14
|
};
|
|
9
15
|
const recommendedConfig = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
const eslintPluginTsTypeForge = {
|
|
25
|
-
meta: {
|
|
26
|
-
name: "eslint-plugin-ts-type-forge"
|
|
27
|
-
},
|
|
28
|
-
rules: tsTypeForgeRules,
|
|
29
|
-
configs: {
|
|
30
|
-
/** Enables every rule of this plugin at `error`. */
|
|
31
|
-
recommended: recommendedConfig
|
|
32
|
-
}
|
|
16
|
+
name: 'ts-type-forge/recommended',
|
|
17
|
+
plugins: {
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
get 'ts-type-forge'() {
|
|
25
|
+
return eslintPluginTsTypeForge;
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
rules: recommendedRules,
|
|
33
29
|
};
|
|
30
|
+
export const eslintPluginTsTypeForge = {
|
|
31
|
+
meta: {
|
|
32
|
+
name: 'eslint-plugin-ts-type-forge',
|
|
33
|
+
},
|
|
34
|
+
rules: tsTypeForgeRules,
|
|
35
|
+
configs: {
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
recommended: recommendedConfig,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=plugin.mjs.map
|
package/dist/plugin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.mjs","
|
|
1
|
+
{"version":3,"file":"plugin.mjs","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG;IACvB,qCAAqC,EAAE,OAAO;IAC9C,yDAAyD,EAAE,OAAO;IAClE,+CAA+C,EAAE,OAAO;IACxD,iDAAiD,EAAE,OAAO;IAC1D,qDAAqD,EAAE,OAAO;CAG/D,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,2BAA2B;IACjC,OAAO,EAAE;QACP,uEAAuE;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,mDAAmD;QACnD,0EAA0E;QAC1E,wDAAwD;QACxD,IAAI,eAAe;YACjB,OAAO,uBAAuB,CAAC;QACjC,CAAC;KACF;IACD,KAAK,EAAE,gBAAgB;CACY,CAAC;AAEtC,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE;QACJ,IAAI,EAAE,6BAA6B;KACpC;IACD,KAAK,EAAE,gBAAgB;IACvB,OAAO,EAAE;QACP,oDAAoD;QACpD,WAAW,EAAE,iBAAiB;KAC/B;CAC8B,CAAC"}
|
package/dist/rule-types.d.mts
CHANGED
|
@@ -9,6 +9,20 @@ type SpreadOptionsIfIsArray<T extends readonly [Linter.StringSeverity, unknown]>
|
|
|
9
9
|
* without converting `meta.schema` (JSON Schema) back into TypeScript types.
|
|
10
10
|
*/
|
|
11
11
|
type RuleOptionsOf<Name extends keyof typeof tsTypeForgeRules> = (typeof tsTypeForgeRules)[Name] extends TSESLint.RuleModule<infer _MessageIds extends string, infer Options extends readonly unknown[]> ? Options : never;
|
|
12
|
+
/**
|
|
13
|
+
* @description Remove a side-effect-only `import 'ts-type-forge';`, which binds no name and has no runtime entry point to resolve to. `ts-type-forge/global` is left alone.
|
|
14
|
+
*
|
|
15
|
+
* ```md
|
|
16
|
+
* | key | value |
|
|
17
|
+
* | :--------- | :------ |
|
|
18
|
+
* | type | problem |
|
|
19
|
+
* | deprecated | false |
|
|
20
|
+
* | fixable | code |
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare namespace NoSideEffectImport {
|
|
24
|
+
type RuleEntry = Linter.StringSeverity;
|
|
25
|
+
}
|
|
12
26
|
/**
|
|
13
27
|
* @description Replace uniform tuple spellings such as `[V, ...V[]]` / `[V, V, ...V[]]` / `[V, V, V]` with the canonical ts-type-forge tuple type.
|
|
14
28
|
*
|
|
@@ -163,6 +177,7 @@ declare namespace PreferStrictOrRelaxedUtilityType {
|
|
|
163
177
|
type RuleEntry = 'off' | Linter.Severity | SpreadOptionsIfIsArray<readonly [Linter.StringSeverity, Options]>;
|
|
164
178
|
}
|
|
165
179
|
export type EslintTsTypeForgeRules = Readonly<{
|
|
180
|
+
'ts-type-forge/no-side-effect-import': NoSideEffectImport.RuleEntry;
|
|
166
181
|
'ts-type-forge/prefer-canonical-length-constrained-tuple': PreferCanonicalLengthConstrainedTuple.RuleEntry;
|
|
167
182
|
'ts-type-forge/prefer-canonical-mutable-record': PreferCanonicalMutableRecord.RuleEntry;
|
|
168
183
|
'ts-type-forge/prefer-readonly-or-mutable-record': PreferReadonlyOrMutableRecord.RuleEntry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"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"}
|
package/dist/rule-types.mjs
CHANGED
package/dist/rule-types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-types.mjs","
|
|
1
|
+
{"version":3,"file":"rule-types.mjs","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAAA,oBAAoB"}
|
package/dist/rules/ast-utils.mjs
CHANGED
|
@@ -1,123 +1,244 @@
|
|
|
1
|
-
import { ASTUtils,
|
|
2
|
-
import { Arr,
|
|
1
|
+
import { AST_NODE_TYPES, ASTUtils, } from '@typescript-eslint/utils';
|
|
2
|
+
import { Arr, hasKey, isNonNullObject, isRecord } from 'ts-data-forge';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export const isLocallyBound = (sourceCode, node, name) => {
|
|
15
|
+
const variable = ASTUtils.findVariable(sourceCode.getScope(node), name);
|
|
16
|
+
return variable !== null && Arr.isNonEmpty(variable.defs);
|
|
7
17
|
};
|
|
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
|
-
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
export const analyzeUniformTuple = (tuple, sourceCode) => {
|
|
39
|
+
if (isInConditionalTypeExtendsClause(tuple))
|
|
40
|
+
return undefined;
|
|
41
|
+
const { parent } = tuple;
|
|
42
|
+
const isReadonly = parent.type === AST_NODE_TYPES.TSTypeOperator &&
|
|
43
|
+
parent.operator === 'readonly';
|
|
44
|
+
const elements = tuple.elementTypes;
|
|
45
|
+
const last = elements.at(-1);
|
|
46
|
+
const hasRest = last?.type === AST_NODE_TYPES.TSRestType;
|
|
47
|
+
const leading = hasRest ? Arr.butLast(elements) : elements;
|
|
48
|
+
if (Arr.isEmpty(leading) ||
|
|
49
|
+
leading.some((element) => element.type === AST_NODE_TYPES.TSRestType ||
|
|
50
|
+
element.type === AST_NODE_TYPES.TSOptionalType ||
|
|
51
|
+
element.type === AST_NODE_TYPES.TSNamedTupleMember)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const restElementType = last !== undefined && hasRest
|
|
55
|
+
? getArrayElementType(last.typeAnnotation)
|
|
56
|
+
: undefined;
|
|
57
|
+
if (hasRest && restElementType === undefined)
|
|
58
|
+
return undefined;
|
|
59
|
+
const [head] = leading;
|
|
60
|
+
if (head === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
const elementText = sourceCode.getText(head);
|
|
63
|
+
const expected = normalizeWhitespace(elementText);
|
|
64
|
+
const others = [
|
|
65
|
+
...Arr.tail(leading),
|
|
66
|
+
...(restElementType === undefined ? [] : [restElementType]),
|
|
67
|
+
];
|
|
68
|
+
if (others.some((element) => normalizeWhitespace(sourceCode.getText(element)) !== expected)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return definesRecursiveTypeAlias(tuple, sourceCode)
|
|
72
|
+
? undefined
|
|
73
|
+
: {
|
|
74
|
+
node: isReadonly ? parent : tuple,
|
|
75
|
+
isReadonly,
|
|
76
|
+
elementText,
|
|
77
|
+
fixedCount: leading.length,
|
|
78
|
+
hasRest,
|
|
79
|
+
};
|
|
43
80
|
};
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
44
92
|
const isInConditionalTypeExtendsClause = (node) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
93
|
+
|
|
94
|
+
if (node.type === AST_NODE_TYPES.Program)
|
|
95
|
+
return false;
|
|
96
|
+
const { parent } = node;
|
|
97
|
+
return ((parent.type === AST_NODE_TYPES.TSConditionalType &&
|
|
98
|
+
parent.extendsType === node) ||
|
|
99
|
+
isInConditionalTypeExtendsClause(parent));
|
|
48
100
|
};
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
49
140
|
const definesRecursiveTypeAlias = (tuple, sourceCode) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
(element) => Array.from(referencedTypeNames(element, sourceCode))
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
141
|
+
const alias = enclosingTypeAlias(tuple);
|
|
142
|
+
if (alias === undefined)
|
|
143
|
+
return false;
|
|
144
|
+
const references = aliasReferenceGraph(programOf(alias), sourceCode);
|
|
145
|
+
const mut_seen = new Set();
|
|
146
|
+
const mut_queue = tuple.elementTypes.flatMap((element) => Array.from(referencedTypeNames(element, sourceCode)));
|
|
147
|
+
while (true) {
|
|
148
|
+
const next = mut_queue.pop();
|
|
149
|
+
if (next === undefined)
|
|
150
|
+
return false;
|
|
151
|
+
if (next === alias.id.name)
|
|
152
|
+
return true;
|
|
153
|
+
if (mut_seen.has(next))
|
|
154
|
+
continue;
|
|
155
|
+
mut_seen.add(next);
|
|
156
|
+
const referenced = references.get(next);
|
|
157
|
+
if (referenced !== undefined) {
|
|
158
|
+
mut_queue.push(...referenced);
|
|
159
|
+
}
|
|
66
160
|
}
|
|
67
|
-
}
|
|
68
161
|
};
|
|
162
|
+
|
|
69
163
|
const enclosingTypeAlias = (node) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
164
|
+
if (node.type === AST_NODE_TYPES.TSTypeAliasDeclaration)
|
|
165
|
+
return node;
|
|
166
|
+
if (node.type === AST_NODE_TYPES.Program)
|
|
167
|
+
return undefined;
|
|
168
|
+
return enclosingTypeAlias(node.parent);
|
|
73
169
|
};
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
74
177
|
const aliasReferenceGraph = (program, sourceCode) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
aliasReferenceGraphCache.set(program, mut_graph);
|
|
87
|
-
return mut_graph;
|
|
178
|
+
const cached = aliasReferenceGraphCache.get(program);
|
|
179
|
+
if (cached !== undefined)
|
|
180
|
+
return cached;
|
|
181
|
+
const mut_graph = new Map();
|
|
182
|
+
walk(program, sourceCode, (visited) => {
|
|
183
|
+
if (visited.type === AST_NODE_TYPES.TSTypeAliasDeclaration) {
|
|
184
|
+
mut_graph.set(visited.id.name, referencedTypeNames(visited.typeAnnotation, sourceCode));
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
aliasReferenceGraphCache.set(program, mut_graph);
|
|
188
|
+
return mut_graph;
|
|
88
189
|
};
|
|
89
|
-
const aliasReferenceGraphCache =
|
|
190
|
+
const aliasReferenceGraphCache = new WeakMap();
|
|
90
191
|
const programOf = (node) => node.type === AST_NODE_TYPES.Program ? node : programOf(node.parent);
|
|
192
|
+
|
|
91
193
|
const referencedTypeNames = (node, sourceCode) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
194
|
+
const mut_names = new Set();
|
|
195
|
+
walk(node, sourceCode, (visited) => {
|
|
196
|
+
if (visited.type === AST_NODE_TYPES.TSTypeReference &&
|
|
197
|
+
visited.typeName.type === AST_NODE_TYPES.Identifier) {
|
|
198
|
+
mut_names.add(visited.typeName.name);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return mut_names;
|
|
99
202
|
};
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
100
212
|
const walk = (node, sourceCode, visit) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
213
|
+
visit(node);
|
|
214
|
+
if (!isRecord(node))
|
|
215
|
+
return;
|
|
216
|
+
const keys = sourceCode.visitorKeys[node.type] ??
|
|
217
|
+
Object.keys(node).filter((key) => key !== 'parent');
|
|
218
|
+
for (const key of keys) {
|
|
219
|
+
const value = hasKey(node, key) ? node[key] : undefined;
|
|
220
|
+
if (Arr.isArray(value)) {
|
|
221
|
+
for (const element of value) {
|
|
222
|
+
if (isNode(element))
|
|
223
|
+
walk(element, sourceCode, visit);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (isNode(value)) {
|
|
227
|
+
walk(value, sourceCode, visit);
|
|
228
|
+
}
|
|
112
229
|
}
|
|
113
|
-
}
|
|
114
230
|
};
|
|
115
|
-
const isNode = (value) => isNonNullObject(value) &&
|
|
231
|
+
const isNode = (value) => isNonNullObject(value) &&
|
|
232
|
+
typeof value.type === 'string';
|
|
233
|
+
|
|
116
234
|
const getArrayElementType = (node) => {
|
|
117
|
-
|
|
118
|
-
|
|
235
|
+
if (node.type === AST_NODE_TYPES.TSArrayType)
|
|
236
|
+
return node.elementType;
|
|
237
|
+
return node.type === AST_NODE_TYPES.TSTypeOperator &&
|
|
238
|
+
node.operator === 'readonly' &&
|
|
239
|
+
node.typeAnnotation?.type === AST_NODE_TYPES.TSArrayType
|
|
240
|
+
? node.typeAnnotation.elementType
|
|
241
|
+
: undefined;
|
|
119
242
|
};
|
|
120
|
-
const normalizeWhitespace = (text) => text.replaceAll(/\s+/gu,
|
|
121
|
-
|
|
122
|
-
export { analyzeUniformTuple, isLocallyBound };
|
|
123
|
-
//# sourceMappingURL=ast-utils.mjs.map
|
|
243
|
+
const normalizeWhitespace = (text) => text.replaceAll(/\s+/gu, ' ').trim();
|
|
244
|
+
//# sourceMappingURL=ast-utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.mjs","sources":["../../src/rules/ast-utils.mts"],"sourcesContent":["import {\n AST_NODE_TYPES,\n ASTUtils,\n type TSESLint,\n type TSESTree,\n} from '@typescript-eslint/utils';\nimport { Arr, hasKey, isNonNullObject, isRecord } from 'ts-data-forge';\n\n/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */\n\n/**\n * Whether `name` resolves to a declaration in this file (a type alias, an\n * interface, a class, an import, …) rather than to the ambient standard-library\n * type of the same name.\n *\n * The `defs` check is what separates the two: ESLint materializes an *implicit*\n * global variable for every unresolved reference, so `findVariable` also\n * succeeds for `Exclude` in a file that never declares it. Only a variable with\n * at least one definition was actually written down somewhere in this file.\n */\nexport const isLocallyBound = (\n sourceCode: TSESLint.SourceCode,\n node: TSESTree.Node,\n name: string,\n): boolean => {\n const variable = ASTUtils.findVariable(sourceCode.getScope(node), name);\n\n return variable !== null && Arr.isNonEmpty(variable.defs);\n};\n\nexport type UniformTupleShape = Readonly<{\n /** The node an autofix must replace: the tuple, or the `readonly` operator. */\n node: TSESTree.Node;\n isReadonly: boolean;\n /** Source text of the (single, shared) element type. */\n elementText: string;\n /** Number of leading fixed-position elements. */\n fixedCount: number;\n /** Whether a trailing `...V[]` rest element is present. */\n hasRest: boolean;\n}>;\n\n/**\n * Recognizes a tuple whose every position has the *same* element type — the\n * hand-rolled spelling of ts-type-forge's length-constrained tuple family:\n *\n * | shape | meaning |\n * | :------------------- | :------------------------- |\n * | `[V, ..., V]` | `FixedLengthTuple<N, V>` |\n * | `[V, ..., V, ...V[]]`| `MinLengthTuple<N, V>` |\n *\n * Returns `undefined` for anything else. Deliberately narrow:\n *\n * - Element types are compared by normalized source text, so heterogeneous\n * tuples are never matched.\n * - Optional (`[V?]`) and labelled (`[head: V]`) members are skipped, since\n * rewriting them would drop information.\n * - A tuple that is only a rest element (`[...V[]]`) is not a length\n * constraint at all.\n * - A tuple inside the `extends` clause of a conditional type is a match\n * pattern, not a type (see {@link isInConditionalTypeExtendsClause}).\n */\nexport const analyzeUniformTuple = (\n tuple: TSESTree.TSTupleType,\n sourceCode: TSESLint.SourceCode,\n): UniformTupleShape | undefined => {\n if (isInConditionalTypeExtendsClause(tuple)) return undefined;\n\n const { parent } = tuple;\n\n const isReadonly =\n parent.type === AST_NODE_TYPES.TSTypeOperator &&\n parent.operator === 'readonly';\n\n const elements = tuple.elementTypes;\n\n const last = elements.at(-1);\n\n const hasRest = last?.type === AST_NODE_TYPES.TSRestType;\n\n const leading = hasRest ? Arr.butLast(elements) : elements;\n\n if (\n Arr.isEmpty(leading) ||\n leading.some(\n (element) =>\n element.type === AST_NODE_TYPES.TSRestType ||\n element.type === AST_NODE_TYPES.TSOptionalType ||\n element.type === AST_NODE_TYPES.TSNamedTupleMember,\n )\n ) {\n return undefined;\n }\n\n const restElementType =\n last !== undefined && hasRest\n ? getArrayElementType(last.typeAnnotation)\n : undefined;\n\n if (hasRest && restElementType === undefined) return undefined;\n\n const [head] = leading;\n\n if (head === undefined) return undefined;\n\n const elementText = sourceCode.getText(head);\n\n const expected = normalizeWhitespace(elementText);\n\n const others = [\n ...Arr.tail(leading),\n ...(restElementType === undefined ? [] : [restElementType]),\n ];\n\n if (\n others.some(\n (element) =>\n normalizeWhitespace(sourceCode.getText(element)) !== expected,\n )\n ) {\n return undefined;\n }\n\n return definesRecursiveTypeAlias(tuple, sourceCode)\n ? undefined\n : {\n node: isReadonly ? parent : tuple,\n isReadonly,\n elementText,\n fixedCount: leading.length,\n hasRest,\n };\n};\n\n/**\n * Whether `node` sits inside the `extends` clause of a conditional type, where\n * a tuple is a *match pattern* rather than a type.\n *\n * `[A, B] extends [true, true]` matches element-wise even while `A` and `B` are\n * still generic. The canonical spellings resolve through a mapped type\n * (`MutableFixedLengthTuple<N, V>` is `Mutable<FixedLengthTuple<N, V>>`), and\n * against one of those the checker defers the whole conditional instead —\n * yielding `boolean` where the tuple pattern yielded `true` or `false`, which\n * silently widens everything downstream. So those positions are left alone.\n */\nconst isInConditionalTypeExtendsClause = (node: TSESTree.Node): boolean => {\n // The root has no parent, so it terminates the walk.\n if (node.type === AST_NODE_TYPES.Program) return false;\n\n const { parent } = node;\n\n return (\n (parent.type === AST_NODE_TYPES.TSConditionalType &&\n parent.extendsType === node) ||\n isInConditionalTypeExtendsClause(parent)\n );\n};\n\n/**\n * Whether the tuple spells out an alias that its own element type leads back\n * to.\n *\n * A tuple literal is how TypeScript's cycle-breaking works: `type T = readonly\n * [T, T]` resolves, because the element positions are deferred. Rewriting it to\n * `FixedLengthTuple<2, T>` routes the same cycle through a mapped type, which\n * the checker will not compute — `T` becomes an error type, and every use of it\n * silently reads as `any`. `tsc` reports the alias once; the typed linter then\n * reports each use, which is how this was found.\n *\n * The cycle is often indirect. `LambdaApplication = readonly [LambdaTerm,\n * LambdaTerm]` looks fine on its own, and only recurses because `LambdaTerm` is\n * a union that includes `LambdaApplication`. So this follows references through\n * the other aliases in the file rather than looking for the enclosing name in\n * the element text.\n *\n * **Any cycle counts, which leaves some rewritable tuples alone.** Not every\n * cycle actually breaks: TypeScript resolves an object type, an array, a tuple\n * and a function type without resolving what is inside them, so `type Pair =\n * FixedLengthTuple<2, Foo>` alongside `type Foo = { p: Pair }` compiles, and so\n * does `type Tree = { kids: FixedLengthTuple<2, Tree> }`. Skipping those\n * constructs while following references was tried and does not hold up — the\n * deferral is undone by anything that asks for the structure, and that can sit\n * anywhere in the file:\n *\n * ```ts\n * type Pair = readonly [Foo, Foo]; // rewriting this breaks Pair and Foo\n * type Foo = Wrapper[number]; // …because of the indexed access here\n * type Wrapper = readonly Pair[];\n * ```\n *\n * Deciding it properly means knowing every use of every alias, which no\n * syntactic rule can do — so a cycle of any shape suppresses the rewrite. The\n * cost is a tuple left spelled out; the alternative is an autofix that turns a\n * type into `any`.\n *\n * A cycle closed through an `import` is not visible here and is not detected.\n */\nconst definesRecursiveTypeAlias = (\n tuple: TSESTree.TSTupleType,\n sourceCode: TSESLint.SourceCode,\n): boolean => {\n const alias = enclosingTypeAlias(tuple);\n\n if (alias === undefined) return false;\n\n const references = aliasReferenceGraph(programOf(alias), sourceCode);\n\n const mut_seen = new Set<string>();\n\n const mut_queue: string[] = tuple.elementTypes.flatMap((element) =>\n Array.from(referencedTypeNames(element, sourceCode)),\n );\n\n while (true) {\n const next = mut_queue.pop();\n\n if (next === undefined) return false;\n\n if (next === alias.id.name) return true;\n\n if (mut_seen.has(next)) continue;\n\n mut_seen.add(next);\n\n const referenced = references.get(next);\n\n if (referenced !== undefined) {\n mut_queue.push(...referenced);\n }\n }\n};\n\n/** The `type X = …` declaration `node` sits in, if any. */\nconst enclosingTypeAlias = (\n node: TSESTree.Node,\n): TSESTree.TSTypeAliasDeclaration | undefined => {\n if (node.type === AST_NODE_TYPES.TSTypeAliasDeclaration) return node;\n\n if (node.type === AST_NODE_TYPES.Program) return undefined;\n\n return enclosingTypeAlias(node.parent);\n};\n\n/**\n * Which other type names each `type X = …` in the file refers to, keyed by `X`.\n *\n * Built once per file and cached on the `Program` node: the search below runs\n * per candidate tuple, and rebuilding this for each of them made the rule cost\n * `O(tuples × file size)` — a full second on the largest generated files here.\n */\nconst aliasReferenceGraph = (\n program: TSESTree.Program,\n sourceCode: TSESLint.SourceCode,\n): ReadonlyMap<string, ReadonlySet<string>> => {\n const cached = aliasReferenceGraphCache.get(program);\n\n if (cached !== undefined) return cached;\n\n const mut_graph = new Map<string, ReadonlySet<string>>();\n\n walk(program, sourceCode, (visited) => {\n if (visited.type === AST_NODE_TYPES.TSTypeAliasDeclaration) {\n mut_graph.set(\n visited.id.name,\n referencedTypeNames(visited.typeAnnotation, sourceCode),\n );\n }\n });\n\n aliasReferenceGraphCache.set(program, mut_graph);\n\n return mut_graph;\n};\n\nconst aliasReferenceGraphCache = new WeakMap<\n TSESTree.Program,\n ReadonlyMap<string, ReadonlySet<string>>\n>();\n\nconst programOf = (node: TSESTree.Node): TSESTree.Program =>\n node.type === AST_NODE_TYPES.Program ? node : programOf(node.parent);\n\n/** The names every `X` / `X<…>` reference in the subtree points at. */\nconst referencedTypeNames = (\n node: TSESTree.Node,\n sourceCode: TSESLint.SourceCode,\n): ReadonlySet<string> => {\n const mut_names = new Set<string>();\n\n walk(node, sourceCode, (visited) => {\n if (\n visited.type === AST_NODE_TYPES.TSTypeReference &&\n visited.typeName.type === AST_NODE_TYPES.Identifier\n ) {\n mut_names.add(visited.typeName.name);\n }\n });\n\n return mut_names;\n};\n\n/**\n * Visits `node` and its descendants.\n *\n * Children are found through the parser's visitor keys, so only the properties\n * that actually hold one are read. Reading every own property instead works\n * too, and is the fallback for a parser that declares no keys for a node type,\n * but it allocates an entry pair per property and walks `loc` / `range` as\n * well — on the generated rule-type files that alone was most of the cost.\n */\nconst walk = (\n node: TSESTree.Node,\n sourceCode: TSESLint.SourceCode,\n visit: (visited: TSESTree.Node) => void,\n): void => {\n visit(node);\n\n if (!isRecord(node)) return;\n\n const keys =\n sourceCode.visitorKeys[node.type] ??\n Object.keys(node).filter((key) => key !== 'parent');\n\n for (const key of keys) {\n const value: unknown = hasKey(node, key) ? node[key] : undefined;\n\n if (Arr.isArray(value)) {\n for (const element of value) {\n if (isNode(element)) walk(element, sourceCode, visit);\n }\n } else if (isNode(value)) {\n walk(value, sourceCode, visit);\n }\n }\n};\n\nconst isNode = (value: unknown): value is TSESTree.Node =>\n isNonNullObject(value) &&\n typeof (value as Readonly<{ type?: unknown }>).type === 'string';\n\n/** Unwraps `V[]` and `readonly V[]` to `V`. */\nconst getArrayElementType = (\n node: TSESTree.TypeNode,\n): TSESTree.TypeNode | undefined => {\n if (node.type === AST_NODE_TYPES.TSArrayType) return node.elementType;\n\n return node.type === AST_NODE_TYPES.TSTypeOperator &&\n node.operator === 'readonly' &&\n node.typeAnnotation?.type === AST_NODE_TYPES.TSArrayType\n ? node.typeAnnotation.elementType\n : undefined;\n};\n\nconst normalizeWhitespace = (text: string): string =>\n text.replaceAll(/\\s+/gu, ' ').trim();\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ast-utils.mjs","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"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"}
|