eslint-config-typed 3.5.2 → 3.7.0

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.
Files changed (187) hide show
  1. package/README.md +2 -2
  2. package/dist/configs/browser.mjs +1 -0
  3. package/dist/configs/browser.mjs.map +1 -1
  4. package/dist/configs/cypress.mjs +1 -0
  5. package/dist/configs/cypress.mjs.map +1 -1
  6. package/dist/configs/jest.mjs +1 -0
  7. package/dist/configs/jest.mjs.map +1 -1
  8. package/dist/configs/nodejs.mjs +1 -0
  9. package/dist/configs/nodejs.mjs.map +1 -1
  10. package/dist/configs/playwright.mjs +1 -0
  11. package/dist/configs/playwright.mjs.map +1 -1
  12. package/dist/configs/plugins.d.mts +1 -1
  13. package/dist/configs/plugins.d.mts.map +1 -1
  14. package/dist/configs/plugins.mjs +3 -2
  15. package/dist/configs/plugins.mjs.map +1 -1
  16. package/dist/configs/react-base.mjs +1 -0
  17. package/dist/configs/react-base.mjs.map +1 -1
  18. package/dist/configs/testing-library.mjs +1 -0
  19. package/dist/configs/testing-library.mjs.map +1 -1
  20. package/dist/configs/typescript.d.mts.map +1 -1
  21. package/dist/configs/typescript.mjs +2 -0
  22. package/dist/configs/typescript.mjs.map +1 -1
  23. package/dist/configs/vitest.mjs +1 -0
  24. package/dist/configs/vitest.mjs.map +1 -1
  25. package/dist/entry-point.d.mts +1 -1
  26. package/dist/entry-point.d.mts.map +1 -1
  27. package/dist/entry-point.mjs +2 -1
  28. package/dist/entry-point.mjs.map +1 -1
  29. package/dist/index.mjs +2 -1
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/plugins/index.d.mts +1 -1
  32. package/dist/plugins/index.d.mts.map +1 -1
  33. package/dist/plugins/index.mjs +1 -1
  34. package/dist/plugins/react-coding-style/rules/component-name.d.mts.map +1 -1
  35. package/dist/plugins/react-coding-style/rules/component-name.mjs.map +1 -1
  36. package/dist/plugins/react-coding-style/rules/import-style.d.mts.map +1 -1
  37. package/dist/plugins/react-coding-style/rules/import-style.mjs.map +1 -1
  38. package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.d.mts.map +1 -1
  39. package/dist/plugins/react-coding-style/rules/react-memo-props-argument-name.mjs.map +1 -1
  40. package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.d.mts.map +1 -1
  41. package/dist/plugins/react-coding-style/rules/react-memo-type-parameter.mjs.map +1 -1
  42. package/dist/plugins/react-coding-style/rules/shared.d.mts.map +1 -1
  43. package/dist/plugins/react-coding-style/rules/shared.mjs.map +1 -1
  44. package/dist/plugins/strict-dependencies/rules/resolve-import-path.d.mts.map +1 -1
  45. package/dist/plugins/strict-dependencies/rules/resolve-import-path.mjs.map +1 -1
  46. package/dist/plugins/strict-dependencies/rules/strict-dependencies.d.mts.map +1 -1
  47. package/dist/plugins/strict-dependencies/rules/strict-dependencies.mjs.map +1 -1
  48. package/dist/plugins/total-functions/rules/no-hidden-type-assertions.d.mts.map +1 -1
  49. package/dist/plugins/total-functions/rules/no-hidden-type-assertions.mjs.map +1 -1
  50. package/dist/plugins/total-functions/rules/no-nested-fp-ts-effects.d.mts.map +1 -1
  51. package/dist/plugins/total-functions/rules/no-nested-fp-ts-effects.mjs.map +1 -1
  52. package/dist/plugins/total-functions/rules/no-partial-division.d.mts.map +1 -1
  53. package/dist/plugins/total-functions/rules/no-partial-division.mjs.map +1 -1
  54. package/dist/plugins/total-functions/rules/no-partial-url-constructor.d.mts.map +1 -1
  55. package/dist/plugins/total-functions/rules/no-partial-url-constructor.mjs.map +1 -1
  56. package/dist/plugins/total-functions/rules/no-premature-fp-ts-effects.d.mts.map +1 -1
  57. package/dist/plugins/total-functions/rules/no-premature-fp-ts-effects.mjs.map +1 -1
  58. package/dist/plugins/total-functions/rules/no-unsafe-mutable-readonly-assignment.d.mts.map +1 -1
  59. package/dist/plugins/total-functions/rules/no-unsafe-mutable-readonly-assignment.mjs.map +1 -1
  60. package/dist/plugins/total-functions/rules/no-unsafe-readonly-mutable-assignment.d.mts.map +1 -1
  61. package/dist/plugins/total-functions/rules/no-unsafe-readonly-mutable-assignment.mjs.map +1 -1
  62. package/dist/plugins/total-functions/rules/require-strict-mode.d.mts.map +1 -1
  63. package/dist/plugins/total-functions/rules/require-strict-mode.mjs.map +1 -1
  64. package/dist/plugins/total-functions/rules/unsafe-assignment-rule.d.mts.map +1 -1
  65. package/dist/plugins/total-functions/rules/unsafe-assignment-rule.mjs.map +1 -1
  66. package/dist/plugins/tree-shakable/rules/import-star.mjs.map +1 -1
  67. package/dist/plugins/ts-restrictions/index.d.mts +2 -0
  68. package/dist/plugins/ts-restrictions/index.d.mts.map +1 -0
  69. package/dist/plugins/ts-restrictions/index.mjs +2 -0
  70. package/dist/plugins/ts-restrictions/plugin.d.mts +3 -0
  71. package/dist/plugins/ts-restrictions/plugin.d.mts.map +1 -0
  72. package/dist/plugins/ts-restrictions/plugin.mjs +8 -0
  73. package/dist/plugins/ts-restrictions/plugin.mjs.map +1 -0
  74. package/dist/plugins/ts-restrictions/rules/index.d.mts.map +1 -0
  75. package/dist/plugins/ts-restrictions/rules/index.mjs +2 -0
  76. package/dist/plugins/ts-restrictions/rules/no-restricted-cast-name.d.mts +17 -0
  77. package/dist/plugins/ts-restrictions/rules/no-restricted-cast-name.d.mts.map +1 -0
  78. package/dist/plugins/ts-restrictions/rules/no-restricted-cast-name.mjs +171 -0
  79. package/dist/plugins/ts-restrictions/rules/no-restricted-cast-name.mjs.map +1 -0
  80. package/dist/plugins/{custom/rules/no-restricted-syntax2.d.mts → ts-restrictions/rules/no-restricted-syntax.d.mts} +1 -1
  81. package/dist/plugins/ts-restrictions/rules/no-restricted-syntax.d.mts.map +1 -0
  82. package/dist/plugins/{custom/rules/no-restricted-syntax2.mjs → ts-restrictions/rules/no-restricted-syntax.mjs} +1 -1
  83. package/dist/plugins/ts-restrictions/rules/no-restricted-syntax.mjs.map +1 -0
  84. package/dist/plugins/ts-restrictions/rules/rules.d.mts +14 -0
  85. package/dist/plugins/ts-restrictions/rules/rules.d.mts.map +1 -0
  86. package/dist/plugins/ts-restrictions/rules/rules.mjs +10 -0
  87. package/dist/plugins/ts-restrictions/rules/rules.mjs.map +1 -0
  88. package/dist/rules/eslint-import-rules.mjs +1 -1
  89. package/dist/rules/eslint-import-rules.mjs.map +1 -1
  90. package/dist/rules/eslint-stylistic-rules.d.mts +17 -1
  91. package/dist/rules/eslint-stylistic-rules.d.mts.map +1 -1
  92. package/dist/rules/eslint-stylistic-rules.mjs +27 -1
  93. package/dist/rules/eslint-stylistic-rules.mjs.map +1 -1
  94. package/dist/rules/eslint-ts-restrictions-rules.d.mts +5 -0
  95. package/dist/rules/eslint-ts-restrictions-rules.d.mts.map +1 -0
  96. package/dist/rules/eslint-ts-restrictions-rules.mjs +7 -0
  97. package/dist/rules/eslint-ts-restrictions-rules.mjs.map +1 -0
  98. package/dist/rules/index.d.mts +1 -0
  99. package/dist/rules/index.d.mts.map +1 -1
  100. package/dist/rules/index.mjs +1 -0
  101. package/dist/rules/index.mjs.map +1 -1
  102. package/dist/types/define-known-rules.d.mts +2 -2
  103. package/dist/types/define-known-rules.d.mts.map +1 -1
  104. package/dist/types/flat-config.d.mts.map +1 -1
  105. package/dist/types/rules/eslint-ts-restrictions-rules.d.mts +150 -0
  106. package/dist/types/rules/eslint-ts-restrictions-rules.d.mts.map +1 -0
  107. package/dist/types/rules/eslint-ts-restrictions-rules.mjs +2 -0
  108. package/dist/types/rules/eslint-ts-restrictions-rules.mjs.map +1 -0
  109. package/dist/types/rules/index.d.mts +1 -1
  110. package/dist/types/rules/index.d.mts.map +1 -1
  111. package/package.json +1 -1
  112. package/src/configs/plugins.mts +4 -3
  113. package/src/configs/typescript.mts +2 -0
  114. package/src/entry-point.mts +1 -1
  115. package/src/plugins/index.mts +1 -1
  116. package/src/plugins/react-coding-style/rules/component-name.mts +1 -0
  117. package/src/plugins/react-coding-style/rules/import-style.mts +1 -0
  118. package/src/plugins/react-coding-style/rules/react-memo-props-argument-name.mts +1 -0
  119. package/src/plugins/react-coding-style/rules/react-memo-type-parameter.mts +4 -0
  120. package/src/plugins/react-coding-style/rules/shared.mts +1 -0
  121. package/src/plugins/strict-dependencies/rules/resolve-import-path.mts +2 -0
  122. package/src/plugins/strict-dependencies/rules/resolve-import-path.test.mts +6 -0
  123. package/src/plugins/strict-dependencies/rules/strict-dependencies.mts +4 -0
  124. package/src/plugins/strict-dependencies/rules/strict-dependencies.test.mts +2 -0
  125. package/src/plugins/total-functions/rules/no-enums.test.mts +4 -3
  126. package/src/plugins/total-functions/rules/no-hidden-type-assertions.mts +3 -0
  127. package/src/plugins/total-functions/rules/no-hidden-type-assertions.test.mts +32 -31
  128. package/src/plugins/total-functions/rules/no-nested-fp-ts-effects.mts +1 -0
  129. package/src/plugins/total-functions/rules/no-nested-fp-ts-effects.test.mts +28 -27
  130. package/src/plugins/total-functions/rules/no-partial-array-reduce.test.mts +25 -24
  131. package/src/plugins/total-functions/rules/no-partial-division.mts +3 -0
  132. package/src/plugins/total-functions/rules/no-partial-division.test.mts +22 -21
  133. package/src/plugins/total-functions/rules/no-partial-string-normalize.test.mts +16 -15
  134. package/src/plugins/total-functions/rules/no-partial-url-constructor.mts +4 -0
  135. package/src/plugins/total-functions/rules/no-partial-url-constructor.test.mts +10 -9
  136. package/src/plugins/total-functions/rules/no-premature-fp-ts-effects.mts +1 -0
  137. package/src/plugins/total-functions/rules/no-premature-fp-ts-effects.test.mts +14 -13
  138. package/src/plugins/total-functions/rules/no-unsafe-mutable-readonly-assignment.mts +1 -0
  139. package/src/plugins/total-functions/rules/no-unsafe-mutable-readonly-assignment.test.mts +483 -482
  140. package/src/plugins/total-functions/rules/no-unsafe-readonly-mutable-assignment.mts +1 -0
  141. package/src/plugins/total-functions/rules/no-unsafe-readonly-mutable-assignment.test.mts +334 -333
  142. package/src/plugins/total-functions/rules/no-unsafe-type-assertion.test.mts +7 -6
  143. package/src/plugins/total-functions/rules/require-strict-mode.mts +1 -0
  144. package/src/plugins/total-functions/rules/unsafe-assignment-rule.mts +4 -0
  145. package/src/plugins/tree-shakable/rules/import-star.mts +8 -0
  146. package/src/plugins/tree-shakable/rules/import-star.test.mts +63 -62
  147. package/src/plugins/ts-restrictions/index.mts +1 -0
  148. package/src/plugins/ts-restrictions/plugin.mts +6 -0
  149. package/src/plugins/ts-restrictions/rules/no-restricted-cast-name.mts +234 -0
  150. package/src/plugins/ts-restrictions/rules/no-restricted-cast-name.test.mts +310 -0
  151. package/src/plugins/ts-restrictions/rules/rules.mts +8 -0
  152. package/src/rules/eslint-import-rules.mts +2 -2
  153. package/src/rules/eslint-stylistic-rules.mts +36 -2
  154. package/src/rules/eslint-ts-restrictions-rules.mts +6 -0
  155. package/src/rules/index.mts +1 -0
  156. package/src/types/define-known-rules.mts +3 -3
  157. package/src/types/flat-config.mts +0 -1
  158. package/src/types/rules/eslint-ts-restrictions-rules.mts +174 -0
  159. package/src/types/rules/index.mts +1 -1
  160. package/dist/plugins/custom/custom.d.mts +0 -3
  161. package/dist/plugins/custom/custom.d.mts.map +0 -1
  162. package/dist/plugins/custom/custom.mjs +0 -8
  163. package/dist/plugins/custom/custom.mjs.map +0 -1
  164. package/dist/plugins/custom/index.d.mts +0 -2
  165. package/dist/plugins/custom/index.d.mts.map +0 -1
  166. package/dist/plugins/custom/index.mjs +0 -2
  167. package/dist/plugins/custom/rules/index.d.mts.map +0 -1
  168. package/dist/plugins/custom/rules/index.mjs +0 -2
  169. package/dist/plugins/custom/rules/no-restricted-syntax2.d.mts.map +0 -1
  170. package/dist/plugins/custom/rules/no-restricted-syntax2.mjs.map +0 -1
  171. package/dist/plugins/custom/rules/rules.d.mts +0 -4
  172. package/dist/plugins/custom/rules/rules.d.mts.map +0 -1
  173. package/dist/plugins/custom/rules/rules.mjs +0 -8
  174. package/dist/plugins/custom/rules/rules.mjs.map +0 -1
  175. package/dist/types/rules/eslint-custom-rules.d.mts +0 -62
  176. package/dist/types/rules/eslint-custom-rules.d.mts.map +0 -1
  177. package/dist/types/rules/eslint-custom-rules.mjs +0 -2
  178. package/dist/types/rules/eslint-custom-rules.mjs.map +0 -1
  179. package/src/plugins/custom/custom.mts +0 -6
  180. package/src/plugins/custom/index.mts +0 -1
  181. package/src/plugins/custom/rules/rules.mts +0 -6
  182. package/src/types/rules/eslint-custom-rules.mts +0 -76
  183. /package/dist/plugins/{custom → ts-restrictions}/index.mjs.map +0 -0
  184. /package/dist/plugins/{custom → ts-restrictions}/rules/index.d.mts +0 -0
  185. /package/dist/plugins/{custom → ts-restrictions}/rules/index.mjs.map +0 -0
  186. /package/src/plugins/{custom → ts-restrictions}/rules/index.mts +0 -0
  187. /package/src/plugins/{custom/rules/no-restricted-syntax2.mts → ts-restrictions/rules/no-restricted-syntax.mts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import parser from '@typescript-eslint/parser';
2
2
  import { RuleTester } from '@typescript-eslint/rule-tester';
3
3
  import { AST_NODE_TYPES } from '@typescript-eslint/utils';
4
+ import dedent from 'dedent';
4
5
  import { noUnsafeMutableReadonlyAssignment } from './no-unsafe-mutable-readonly-assignment.mjs';
5
6
 
6
7
  const ruleTester = new RuleTester({
@@ -22,180 +23,180 @@ ruleTester.run(
22
23
  // zero parameters
23
24
  {
24
25
  filename: 'file.ts',
25
- code: `
26
- const foo = () => {
27
- return undefined;
28
- };
29
- foo();
30
- `,
26
+ code: dedent`
27
+ const foo = () => {
28
+ return undefined;
29
+ };
30
+ foo();
31
+ `,
31
32
  },
32
33
  // zero parameters with extra argument (TypeScript will catch this so we don't flag it)
33
34
  {
34
35
  filename: 'file.ts',
35
- code: `
36
- const foo = () => {
37
- return undefined;
38
- };
39
- foo("");
40
- `,
36
+ code: dedent`
37
+ const foo = () => {
38
+ return undefined;
39
+ };
40
+ foo("");
41
+ `,
41
42
  },
42
43
  // non-object parameter
43
44
  {
44
45
  filename: 'file.ts',
45
- code: `
46
- const foo = (a: string) => {
47
- return undefined;
48
- };
49
- foo("a");
50
- `,
46
+ code: dedent`
47
+ const foo = (a: string) => {
48
+ return undefined;
49
+ };
50
+ foo("a");
51
+ `,
51
52
  },
52
53
  // missing arguments (TypeScript will catch this so we don't flag it)
53
54
  {
54
55
  filename: 'file.ts',
55
- code: `
56
- const foo = (a: string) => {
57
- return undefined;
58
- };
59
- foo();
60
- `,
56
+ code: dedent`
57
+ const foo = (a: string) => {
58
+ return undefined;
59
+ };
60
+ foo();
61
+ `,
61
62
  },
62
63
  // readonly -> readonly (nested object; type doesn't change)
63
64
  {
64
65
  filename: 'file.ts',
65
- code: `
66
- type ReadonlyA = { readonly a: { readonly b: string } };
67
- const func = (param: ReadonlyA): void => {
68
- return undefined;
69
- };
70
- const readonlyA = { a: { b: "" } } as const;
71
- func(readonlyA);
72
- `,
66
+ code: dedent`
67
+ type ReadonlyA = { readonly a: { readonly b: string } };
68
+ const func = (param: ReadonlyA): void => {
69
+ return undefined;
70
+ };
71
+ const readonlyA = { a: { b: "" } } as const;
72
+ func(readonlyA);
73
+ `,
73
74
  },
74
75
  // mutable -> mutable (type doesn't change)
75
76
  {
76
77
  filename: 'file.ts',
77
- code: `
78
- type MutableA = {a: string};
79
- const foo = (mut: MutableA) => {
80
- mut.a = "whoops";
81
- };
82
- const mut: MutableA = { a: "" };
83
- foo(mut);
84
- `,
78
+ code: dedent`
79
+ type MutableA = {a: string};
80
+ const foo = (mut: MutableA) => {
81
+ mut.a = "whoops";
82
+ };
83
+ const mut: MutableA = { a: "" };
84
+ foo(mut);
85
+ `,
85
86
  },
86
87
  // object literal -> mutable (no reference to object retained)
87
88
  {
88
89
  filename: 'file.ts',
89
- code: `
90
- type MutableA = {a: string};
91
- const foo = (mut: MutableA) => {
92
- mut.a = "whoops";
93
- };
94
- foo({ a: "" });
95
- `,
90
+ code: dedent`
91
+ type MutableA = {a: string};
92
+ const foo = (mut: MutableA) => {
93
+ mut.a = "whoops";
94
+ };
95
+ foo({ a: "" });
96
+ `,
96
97
  },
97
98
  // object literal -> mutable (mutable reference to property retained)
98
99
  {
99
100
  filename: 'file.ts',
100
- code: `
101
- type MutableB = { b: string };
102
- type MutableA = { readonly a: MutableB };
103
- const func = (param: MutableA): void => {
104
- return undefined;
105
- };
106
- const b: MutableB = { b: "" };
107
- func({ a: b } as const);
108
- `,
101
+ code: dedent`
102
+ type MutableB = { b: string };
103
+ type MutableA = { readonly a: MutableB };
104
+ const func = (param: MutableA): void => {
105
+ return undefined;
106
+ };
107
+ const b: MutableB = { b: "" };
108
+ func({ a: b } as const);
109
+ `,
109
110
  },
110
111
  // object literal -> readonly (readonly reference to property retained)
111
112
  {
112
113
  filename: 'file.ts',
113
- code: `
114
- type ReadonlyB = { readonly b: string };
115
- type ReadonlyA = { readonly a: ReadonlyB };
116
- const func = (param: ReadonlyA): void => {
117
- return undefined;
118
- };
119
- const b: ReadonlyB = { b: "" } as const;
120
- func({ a: b } as const);
121
- `,
114
+ code: dedent`
115
+ type ReadonlyB = { readonly b: string };
116
+ type ReadonlyA = { readonly a: ReadonlyB };
117
+ const func = (param: ReadonlyA): void => {
118
+ return undefined;
119
+ };
120
+ const b: ReadonlyB = { b: "" } as const;
121
+ func({ a: b } as const);
122
+ `,
122
123
  },
123
124
  // object literal -> readonly (no reference to object or its property retained)
124
125
  {
125
126
  filename: 'file.ts',
126
- code: `
127
- type ReadonlyB = { readonly b: string };
128
- type ReadonlyA = { readonly a: ReadonlyB };
129
- const func = (param: ReadonlyA): void => {
130
- return undefined;
131
- };
132
- func({ a: { b: "" } } as const);
133
- `,
127
+ code: dedent`
128
+ type ReadonlyB = { readonly b: string };
129
+ type ReadonlyA = { readonly a: ReadonlyB };
130
+ const func = (param: ReadonlyA): void => {
131
+ return undefined;
132
+ };
133
+ func({ a: { b: "" } } as const);
134
+ `,
134
135
  },
135
136
  // mutable (union) -> mutable
136
137
  {
137
138
  filename: 'file.ts',
138
- code: `
139
- type MutableA = {a: string};
140
- const foo = (mut: MutableA) => {
141
- mut.a = "whoops";
142
- };
143
- const mut: MutableA | number = { a: "" };
144
- foo(mut);
145
- `,
139
+ code: dedent`
140
+ type MutableA = {a: string};
141
+ const foo = (mut: MutableA) => {
142
+ mut.a = "whoops";
143
+ };
144
+ const mut: MutableA | number = { a: "" };
145
+ foo(mut);
146
+ `,
146
147
  },
147
148
  // mutable -> mutable (union)
148
149
  {
149
150
  filename: 'file.ts',
150
- code: `
151
- type MutableA = {a: string};
152
- const foo = (mut: MutableA | number): void => {
153
- return;
154
- };
155
- const mut: MutableA = { a: "" };
156
- foo(mut);
157
- `,
151
+ code: dedent`
152
+ type MutableA = {a: string};
153
+ const foo = (mut: MutableA | number): void => {
154
+ return;
155
+ };
156
+ const mut: MutableA = { a: "" };
157
+ foo(mut);
158
+ `,
158
159
  },
159
160
  // multiple type signatures (readonly -> readonly)
160
161
  {
161
162
  filename: 'file.ts',
162
- code: `
163
- type ReadonlyA = { readonly a: string };
164
-
165
- export function func(a: number): number;
166
- export function func(a: ReadonlyA): ReadonlyA;
167
- export function func(a: any): any {
168
- return a;
169
- }
170
-
171
- const readonlyA: ReadonlyA = { a: "" } as const;
172
- func(readonlyA);
173
- `,
163
+ code: dedent`
164
+ type ReadonlyA = { readonly a: string };
165
+
166
+ export function func(a: number): number;
167
+ export function func(a: ReadonlyA): ReadonlyA;
168
+ export function func(a: any): any {
169
+ return a;
170
+ }
171
+
172
+ const readonlyA: ReadonlyA = { a: "" } as const;
173
+ func(readonlyA);
174
+ `,
174
175
  },
175
176
  // multiple type signatures (no matching signature)
176
177
  // we don't bother flagging this because TypeScript itself will catch it
177
178
  {
178
179
  filename: 'file.ts',
179
- code: `
180
- type ReadonlyA = { readonly a: string };
181
-
182
- export function func(a: number): number;
183
- export function func(a: string): string;
184
- export function func(a: any): any {
185
- return a;
186
- }
187
-
188
- const readonlyA: ReadonlyA = { a: "" } as const;
189
- func(readonlyA);
190
- `,
180
+ code: dedent`
181
+ type ReadonlyA = { readonly a: string };
182
+
183
+ export function func(a: number): number;
184
+ export function func(a: string): string;
185
+ export function func(a: any): any {
186
+ return a;
187
+ }
188
+
189
+ const readonlyA: ReadonlyA = { a: "" } as const;
190
+ func(readonlyA);
191
+ `,
191
192
  },
192
193
  // readonly array concat.
193
194
  {
194
195
  filename: 'file.ts',
195
- code: `
196
- const arr: ReadonlyArray<never> = [] as const;
197
- const foo = arr.concat(arr, arr);
198
- `,
196
+ code: dedent`
197
+ const arr: ReadonlyArray<never> = [] as const;
198
+ const foo = arr.concat(arr, arr);
199
+ `,
199
200
  },
200
201
  // TODO: https://github.com/danielnixon/eslint-plugin-total-functions/issues/132
201
202
  // // mutable array concat.
@@ -219,367 +220,367 @@ ruleTester.run(
219
220
  // The `readonly`s align and `mutable`s align, so no surprising mutation can arise.
220
221
  {
221
222
  filename: 'file.ts',
222
- code: `
223
- type MutableA = { a: string };
224
- type ReadonlyB = { readonly b: string };
225
- const func = (foo: MutableA | ReadonlyB): void => {
226
- return;
227
- };
228
- const foo: MutableA | ReadonlyB = Date.now() > 0 ? { a: "" } : { b: "" } as const;
229
- func(foo);
230
- `,
223
+ code: dedent`
224
+ type MutableA = { a: string };
225
+ type ReadonlyB = { readonly b: string };
226
+ const func = (foo: MutableA | ReadonlyB): void => {
227
+ return;
228
+ };
229
+ const foo: MutableA | ReadonlyB = Date.now() > 0 ? { a: "" } : { b: "" } as const;
230
+ func(foo);
231
+ `,
231
232
  },
232
233
  // readonly array of readonly object -> readonly array of readonly object
233
234
  {
234
235
  filename: 'file.ts',
235
- code: `
236
- type Obj = { readonly foo: string };
237
- const foo = (a: ReadonlyArray<Obj>): number => a.length;
238
- const arr: ReadonlyArray<Obj> = [] as const;
239
- foo(arr);
240
- `,
236
+ code: dedent`
237
+ type Obj = { readonly foo: string };
238
+ const foo = (a: ReadonlyArray<Obj>): number => a.length;
239
+ const arr: ReadonlyArray<Obj> = [] as const;
240
+ foo(arr);
241
+ `,
241
242
  },
242
243
  /** Assignment expressions */
243
244
  // TODO
244
245
  // Array safe mutable to readonly assignment with chained array operations.
245
246
  {
246
247
  filename: 'file.ts',
247
- code: `
248
- const fooArray: readonly string[] = ["test"] as const;
249
- const nextArray: readonly string[] = fooArray.filter((v) => v.length > 0).map((v) => v.length.toString());
250
- `,
248
+ code: dedent`
249
+ const fooArray: readonly string[] = ["test"] as const;
250
+ const nextArray: readonly string[] = fooArray.filter((v) => v.length > 0).map((v) => v.length.toString());
251
+ `,
251
252
  },
252
253
  // Array safe mutable to readonly assignment. (array.filter)
253
254
  {
254
255
  filename: 'file.ts',
255
- code: `
256
- const fooArray: readonly string[] = [""] as const;
257
- const nextArray: readonly string[] = fooArray.filter((v) => v.length > 0);
258
- `,
256
+ code: dedent`
257
+ const fooArray: readonly string[] = [""] as const;
258
+ const nextArray: readonly string[] = fooArray.filter((v) => v.length > 0);
259
+ `,
259
260
  },
260
261
  // Array safe mutable to readonly assignment. (array.map)
261
262
  {
262
263
  filename: 'file.ts',
263
- code: `
264
- const fooArray: readonly string[] = ["test"] as const;
265
- const nextArray: readonly string[] = fooArray.map((v) => v.length.toString());
266
- `,
264
+ code: dedent`
265
+ const fooArray: readonly string[] = ["test"] as const;
266
+ const nextArray: readonly string[] = fooArray.map((v) => v.length.toString());
267
+ `,
267
268
  },
268
269
  // Array safe mutable to readonly assignment. (array.concat)
269
270
  {
270
271
  filename: 'file.ts',
271
- code: `
272
- const fooArray: readonly string[] = ["test-1"] as const;
273
- const booArray: readonly string[] = ["test-2"] as const;
274
- const nextArray: readonly string[] = fooArray.concat(booArray);
275
- `,
272
+ code: dedent`
273
+ const fooArray: readonly string[] = ["test-1"] as const;
274
+ const booArray: readonly string[] = ["test-2"] as const;
275
+ const nextArray: readonly string[] = fooArray.concat(booArray);
276
+ `,
276
277
  },
277
278
  // Array safe mutable to readonly assignment. (array.flatMap)
278
279
  {
279
280
  filename: 'file.ts',
280
- code: `
281
- const fooArray: readonly string[][] = [["test"]] as const;
282
- const nextArray: readonly string[] = fooArray.flatMap((v) => v.length.toString());
283
- `,
281
+ code: dedent`
282
+ const fooArray: readonly string[][] = [["test"]] as const;
283
+ const nextArray: readonly string[] = fooArray.flatMap((v) => v.length.toString());
284
+ `,
284
285
  },
285
286
  // Array safe mutable to readonly assignment. (array.flat)
286
287
  {
287
288
  filename: 'file.ts',
288
- code: `
289
- const fooArray: readonly string[][] = [["test"]] as const;
290
- const nextArray: readonly string[] = fooArray.flat();
291
- `,
289
+ code: dedent`
290
+ const fooArray: readonly string[][] = [["test"]] as const;
291
+ const nextArray: readonly string[] = fooArray.flat();
292
+ `,
292
293
  },
293
294
  // Array safe mutable to readonly assignment. (array.slice)
294
295
  {
295
296
  filename: 'file.ts',
296
- code: `
297
- const fooArray: readonly string[] = ["test"] as const;
298
- const nextArray: readonly string[] = fooArray.slice();
299
- `,
297
+ code: dedent`
298
+ const fooArray: readonly string[] = ["test"] as const;
299
+ const nextArray: readonly string[] = fooArray.slice();
300
+ `,
300
301
  },
301
302
  /** Return statement */
302
303
  // mutable -> mutable (function return)
303
304
  {
304
305
  filename: 'file.ts',
305
- code: `
306
- type MutableA = { a: string };
307
- type ReadonlyA = { readonly a: string };
308
-
309
- function foo(): MutableA {
310
- const ma: MutableA = { a: "" };
311
- return ma;
312
- }
313
- `,
306
+ code: dedent`
307
+ type MutableA = { a: string };
308
+ type ReadonlyA = { readonly a: string };
309
+
310
+ function foo(): MutableA {
311
+ const ma: MutableA = { a: "" };
312
+ return ma;
313
+ }
314
+ `,
314
315
  },
315
316
  // readonly -> readonly (function return)
316
317
  {
317
318
  filename: 'file.ts',
318
- code: `
319
- type MutableA = { a: string };
320
- type ReadonlyA = { readonly a: string };
321
-
322
- function foo(): ReadonlyA {
323
- const ma: ReadonlyA = { a: "" } as const;
324
- return ma;
325
- }
326
- `,
319
+ code: dedent`
320
+ type MutableA = { a: string };
321
+ type ReadonlyA = { readonly a: string };
322
+
323
+ function foo(): ReadonlyA {
324
+ const ma: ReadonlyA = { a: "" } as const;
325
+ return ma;
326
+ }
327
+ `,
327
328
  },
328
329
  // mutable -> mutable (type changes)
329
330
  {
330
331
  filename: 'file.ts',
331
- code: `
332
- type MutableA = { a: string };
333
- type MutableB = { a: string | null };
334
- const foo = (mut: MutableB): void => {
335
- mut.a = null; // whoops
336
- };
337
- const mut: MutableA = { a: "" };
338
- foo(mut);
339
- `,
332
+ code: dedent`
333
+ type MutableA = { a: string };
334
+ type MutableB = { a: string | null };
335
+ const foo = (mut: MutableB): void => {
336
+ mut.a = null; // whoops
337
+ };
338
+ const mut: MutableA = { a: "" };
339
+ foo(mut);
340
+ `,
340
341
  },
341
342
  // tuple -> readonly array (nested objected property)
342
343
  {
343
344
  filename: 'file.ts',
344
- code: `
345
- type Foo = {
346
- readonly foo: ReadonlyArray<{
347
- readonly a: string;
348
- readonly b: string;
349
- }>;
350
- };
351
-
352
- const f: Foo = {
353
- foo: [{
354
- a: "",
355
- b: "",
356
- }],
357
- } as const;
358
- `,
345
+ code: dedent`
346
+ type Foo = {
347
+ readonly foo: ReadonlyArray<{
348
+ readonly a: string;
349
+ readonly b: string;
350
+ }>;
351
+ };
352
+
353
+ const f: Foo = {
354
+ foo: [{
355
+ a: "",
356
+ b: "",
357
+ }],
358
+ } as const;
359
+ `,
359
360
  },
360
361
  // mutable function return -> mutable function return (multiple call signatures).
361
362
  {
362
363
  filename: 'file.ts',
363
- code: `
364
- type MutableA = { a: string };
365
-
366
- interface MutableFunc {
367
- (b: number): MutableA;
368
- (b: string): MutableA;
369
- }
370
-
371
- const mf: MutableFunc = (b: number | string): MutableA => {
372
- return { a: "" };
373
- };
374
-
375
- const rf: MutableFunc = mf;
376
- `,
364
+ code: dedent`
365
+ type MutableA = { a: string };
366
+
367
+ interface MutableFunc {
368
+ (b: number): MutableA;
369
+ (b: string): MutableA;
370
+ }
371
+
372
+ const mf: MutableFunc = (b: number | string): MutableA => {
373
+ return { a: "" };
374
+ };
375
+
376
+ const rf: MutableFunc = mf;
377
+ `,
377
378
  },
378
379
  // readonly function return -> readonly function return (multiple call signatures).
379
380
  {
380
381
  filename: 'file.ts',
381
- code: `
382
- type ReadonlyA = { readonly a: string };
383
-
384
- interface ReadonlyFunc {
385
- (b: number): ReadonlyA;
386
- (b: string): ReadonlyA;
387
- }
388
-
389
- const mf: ReadonlyFunc = (b: number | string): ReadonlyA => {
390
- return { a: "" } as const;
391
- };
392
-
393
- const rf: ReadonlyFunc = mf;
394
- `,
382
+ code: dedent`
383
+ type ReadonlyA = { readonly a: string };
384
+
385
+ interface ReadonlyFunc {
386
+ (b: number): ReadonlyA;
387
+ (b: string): ReadonlyA;
388
+ }
389
+
390
+ const mf: ReadonlyFunc = (b: number | string): ReadonlyA => {
391
+ return { a: "" } as const;
392
+ };
393
+
394
+ const rf: ReadonlyFunc = mf;
395
+ `,
395
396
  },
396
397
  // Return empty tuple from function that is declared to return some readonly array type.
397
398
  {
398
399
  filename: 'file.ts',
399
- code: `
400
- type Foo = ReadonlyArray<{ readonly a: string }>;
401
- const foo = (): Foo => {
402
- return [] as const;
403
- };
404
- `,
400
+ code: dedent`
401
+ type Foo = ReadonlyArray<{ readonly a: string }>;
402
+ const foo = (): Foo => {
403
+ return [] as const;
404
+ };
405
+ `,
405
406
  },
406
407
  // Return empty tuple from function that is declared to return empty tuple.
407
408
  {
408
409
  filename: 'file.ts',
409
- code: `
410
- type Foo = readonly [];
411
- const foo = (): Foo => {
412
- return [] as const;
413
- };
414
- `,
410
+ code: dedent`
411
+ type Foo = readonly [];
412
+ const foo = (): Foo => {
413
+ return [] as const;
414
+ };
415
+ `,
415
416
  },
416
417
  // Return safe mutable array with chained array operations.
417
418
  {
418
419
  filename: 'file.ts',
419
- code: `
420
- const fooArray: readonly string[] = ["test"] as const;
421
- const nextArray = (): readonly string[] => fooArray.filter((v) => v.length > 0).map((v) => v.length.toString());
422
- `,
420
+ code: dedent`
421
+ const fooArray: readonly string[] = ["test"] as const;
422
+ const nextArray = (): readonly string[] => fooArray.filter((v) => v.length > 0).map((v) => v.length.toString());
423
+ `,
423
424
  },
424
425
  // Return safe mutable array. (array.filter)
425
426
  {
426
427
  filename: 'file.ts',
427
- code: `
428
- const fooArray: readonly string[] = [""] as const;
429
- const nextArray = (): readonly string[] => fooArray.filter((v) => v.length > 0);
430
- `,
428
+ code: dedent`
429
+ const fooArray: readonly string[] = [""] as const;
430
+ const nextArray = (): readonly string[] => fooArray.filter((v) => v.length > 0);
431
+ `,
431
432
  },
432
433
  // Return safe mutable array. (array.map)
433
434
  {
434
435
  filename: 'file.ts',
435
- code: `
436
- const fooArray: readonly string[] = ["test"] as const;
437
- const nextArray = (): readonly string[] => fooArray.map((v) => v.length.toString());
438
- `,
436
+ code: dedent`
437
+ const fooArray: readonly string[] = ["test"] as const;
438
+ const nextArray = (): readonly string[] => fooArray.map((v) => v.length.toString());
439
+ `,
439
440
  },
440
441
  // Return safe mutable array. (array.concat)
441
442
  {
442
443
  filename: 'file.ts',
443
- code: `
444
- const fooArray: readonly string[] = ["test-1"] as const;
445
- const booArray: readonly string[] = ["test-2"] as const;
446
- const nextArray = (): readonly string[] => fooArray.concat(booArray);
447
- `,
444
+ code: dedent`
445
+ const fooArray: readonly string[] = ["test-1"] as const;
446
+ const booArray: readonly string[] = ["test-2"] as const;
447
+ const nextArray = (): readonly string[] => fooArray.concat(booArray);
448
+ `,
448
449
  },
449
450
  // Return safe mutable array. (array.flatMap)
450
451
  {
451
452
  filename: 'file.ts',
452
- code: `
453
- const fooArray: readonly string[][] = [["test"]] as const;
454
- const nextArray = (): readonly string[] => fooArray.flatMap((v) => v.length.toString());
455
- `,
453
+ code: dedent`
454
+ const fooArray: readonly string[][] = [["test"]] as const;
455
+ const nextArray = (): readonly string[] => fooArray.flatMap((v) => v.length.toString());
456
+ `,
456
457
  },
457
458
  // Return safe mutable array. (array.flat)
458
459
  {
459
460
  filename: 'file.ts',
460
- code: `
461
- const fooArray: readonly string[][] = [["test"]] as const;
462
- const nextArray = (): readonly string[] => fooArray.flat();
463
- `,
461
+ code: dedent`
462
+ const fooArray: readonly string[][] = [["test"]] as const;
463
+ const nextArray = (): readonly string[] => fooArray.flat();
464
+ `,
464
465
  },
465
466
  // Return safe mutable array. (array.slice)
466
467
  {
467
468
  filename: 'file.ts',
468
- code: `
469
- const fooArray: readonly string[] = ["test"] as const;
470
- const nextArray = (): readonly string[] => fooArray.slice();
471
- `,
469
+ code: dedent`
470
+ const fooArray: readonly string[] = ["test"] as const;
471
+ const nextArray = (): readonly string[] => fooArray.slice();
472
+ `,
472
473
  },
473
474
  // Return safe mutable array.
474
475
  {
475
476
  filename: 'file.ts',
476
- code: `
477
- const fooArray: readonly string[] = ["test"] as const;
478
- const nextArray = (): readonly string[] => {
479
- return fooArray.slice();
480
- }
481
- `,
477
+ code: dedent`
478
+ const fooArray: readonly string[] = ["test"] as const;
479
+ const nextArray = (): readonly string[] => {
480
+ return fooArray.slice();
481
+ }
482
+ `,
482
483
  },
483
484
  // Yield safe mutable array.
484
485
  {
485
486
  filename: 'file.ts',
486
- code: `
487
- const fooArray: readonly string[] = ["test"] as const;
488
- export function* mySaga(): Generator<readonly string[]> {
489
- yield fooArray.slice();
490
- }
491
- `,
487
+ code: dedent`
488
+ const fooArray: readonly string[] = ["test"] as const;
489
+ export function* mySaga(): Generator<readonly string[]> {
490
+ yield fooArray.slice();
491
+ }
492
+ `,
492
493
  },
493
494
  // generators
494
495
  {
495
496
  filename: 'file.ts',
496
- code: `
497
- export function* mySaga(): Generator<void> {
498
- yield;
499
- }
500
- `,
497
+ code: dedent`
498
+ export function* mySaga(): Generator<void> {
499
+ yield;
500
+ }
501
+ `,
501
502
  },
502
503
  // The five turtles.
503
504
  // https://effectivetypescript.com/2021/05/06/unsoundness/#There-Are-Five-Turtles
504
505
  // https://www.youtube.com/watch?v=wpgKd-rwnMw&t=1714s
505
506
  {
506
507
  filename: 'file.ts',
507
- code: `
508
- type Foo<U> = {
509
- readonly a: U;
510
- readonly b: Foo<Foo<U>>;
511
- };
512
-
513
- type Bar<U> = {
514
- readonly a: U;
515
- readonly b: Bar<Bar<U>>;
516
- };
517
-
518
- declare const foo: Foo<string>;
519
-
520
- const bar: Bar<string> = foo;
521
- `,
522
- },
523
- {
524
- filename: 'file.ts',
525
- code: `
526
- type Foo<U> = {
527
- readonly a: U;
528
- readonly b: () => Foo<Foo<U>>;
529
- };
530
-
531
- type Bar<U> = {
532
- readonly a: U;
533
- readonly b: () => Bar<Bar<U>>;
534
- };
535
-
536
- declare const foo: Foo<string>;
537
-
538
- const bar: Bar<string> = foo;
539
- `,
508
+ code: dedent`
509
+ type Foo<U> = {
510
+ readonly a: U;
511
+ readonly b: Foo<Foo<U>>;
512
+ };
513
+
514
+ type Bar<U> = {
515
+ readonly a: U;
516
+ readonly b: Bar<Bar<U>>;
517
+ };
518
+
519
+ declare const foo: Foo<string>;
520
+
521
+ const bar: Bar<string> = foo;
522
+ `,
523
+ },
524
+ {
525
+ filename: 'file.ts',
526
+ code: dedent`
527
+ type Foo<U> = {
528
+ readonly a: U;
529
+ readonly b: () => Foo<Foo<U>>;
530
+ };
531
+
532
+ type Bar<U> = {
533
+ readonly a: U;
534
+ readonly b: () => Bar<Bar<U>>;
535
+ };
536
+
537
+ declare const foo: Foo<string>;
538
+
539
+ const bar: Bar<string> = foo;
540
+ `,
540
541
  },
541
542
  // Return empty array literal from function that is declared to return empty tuple.
542
543
  {
543
544
  filename: 'file.ts',
544
- code: `
545
- const foo = (): readonly [] => {
546
- return [];
547
- };
548
- `,
545
+ code: dedent`
546
+ const foo = (): readonly [] => {
547
+ return [];
548
+ };
549
+ `,
549
550
  },
550
551
  // https://github.com/danielnixon/eslint-plugin-total-functions/issues/741
551
552
  {
552
553
  filename: 'file.ts',
553
- code: `
554
- type Foo<U> = {
555
- b?: Foo<Foo<U>>;
556
- };
557
-
558
- const takesAFoo = <U>(foo: Foo<U>): void => {
559
- return undefined;
560
- }
561
-
562
- let foo: Foo<unknown> = { b: {} };
563
-
564
- foo.b = foo;
565
-
566
- takesAFoo(foo);
567
- `,
554
+ code: dedent`
555
+ type Foo<U> = {
556
+ b?: Foo<Foo<U>>;
557
+ };
558
+
559
+ const takesAFoo = <U>(foo: Foo<U>): void => {
560
+ return undefined;
561
+ }
562
+
563
+ let foo: Foo<unknown> = { b: {} };
564
+
565
+ foo.b = foo;
566
+
567
+ takesAFoo(foo);
568
+ `,
568
569
  },
569
570
  {
570
571
  filename: 'file.ts',
571
- code: `
572
- declare const fooArray: readonly string[];
573
- declare const takesReadonly: (a: readonly string[]) => void;
574
- const nextArray: readonly string[] = takesReadonly(fooArray.slice());
575
- `,
572
+ code: dedent`
573
+ declare const fooArray: readonly string[];
574
+ declare const takesReadonly: (a: readonly string[]) => void;
575
+ const nextArray: readonly string[] = takesReadonly(fooArray.slice());
576
+ `,
576
577
  },
577
578
  // Literal (mutable) assigned to immutable but safe because no surprising mutation can arise
578
579
  {
579
580
  filename: 'file.ts',
580
- code: `
581
- const o: readonly string[] = [];
582
- `,
581
+ code: dedent`
582
+ const o: readonly string[] = [];
583
+ `,
583
584
  },
584
585
  ],
585
586
  invalid: [
@@ -587,10 +588,10 @@ ruleTester.run(
587
588
  // TODO this should ideally be considered valid without requiring an `as const`.
588
589
  {
589
590
  filename: 'file.ts',
590
- code: `
591
- type ReadonlyA = { readonly a: string };
592
- const readonlyA: ReadonlyA = { a: "" };
593
- `,
591
+ code: dedent`
592
+ type ReadonlyA = { readonly a: string };
593
+ const readonlyA: ReadonlyA = { a: "" };
594
+ `,
594
595
  errors: [
595
596
  {
596
597
  messageId: 'errorStringGeneric',
@@ -621,15 +622,15 @@ ruleTester.run(
621
622
  // mutable -> readonly
622
623
  {
623
624
  filename: 'file.ts',
624
- code: `
625
- type MutableA = { a: string };
626
- type ReadonlyA = Readonly<MutableA>;
627
- const func = (param: ReadonlyA): void => {
628
- return undefined;
629
- };
630
- const mutableA: MutableA = { a: "" };
631
- func(mutableA);
632
- `,
625
+ code: dedent`
626
+ type MutableA = { a: string };
627
+ type ReadonlyA = Readonly<MutableA>;
628
+ const func = (param: ReadonlyA): void => {
629
+ return undefined;
630
+ };
631
+ const mutableA: MutableA = { a: "" };
632
+ func(mutableA);
633
+ `,
633
634
  errors: [
634
635
  {
635
636
  messageId: 'errorStringGeneric',
@@ -640,15 +641,15 @@ ruleTester.run(
640
641
  // mutable -> readonly (function return)
641
642
  {
642
643
  filename: 'file.ts',
643
- code: `
644
- type MutableA = { a: string };
645
- type ReadonlyA = { readonly a: string };
646
-
647
- function foo(): ReadonlyA {
648
- const ma: MutableA = { a: "" };
649
- return ma;
650
- }
651
- `,
644
+ code: dedent`
645
+ type MutableA = { a: string };
646
+ type ReadonlyA = { readonly a: string };
647
+
648
+ function foo(): ReadonlyA {
649
+ const ma: MutableA = { a: "" };
650
+ return ma;
651
+ }
652
+ `,
652
653
  errors: [
653
654
  {
654
655
  messageId: 'errorStringGeneric',
@@ -659,13 +660,13 @@ ruleTester.run(
659
660
  // mutable object prop -> readonly object prop (as part of intersection with non-object).
660
661
  {
661
662
  filename: 'file.ts',
662
- code: `
663
- type MutableA = { a?: string } & number;
664
- type ReadonlyA = { readonly a?: string } & number;
665
-
666
- const ma: MutableA = 42;
667
- const ra: ReadonlyA = ma;
668
- `,
663
+ code: dedent`
664
+ type MutableA = { a?: string } & number;
665
+ type ReadonlyA = { readonly a?: string } & number;
666
+
667
+ const ma: MutableA = 42;
668
+ const ra: ReadonlyA = ma;
669
+ `,
669
670
  errors: [
670
671
  {
671
672
  messageId: 'errorStringGeneric',
@@ -676,17 +677,17 @@ ruleTester.run(
676
677
  // mutable function value -> readonly.
677
678
  {
678
679
  filename: 'file.ts',
679
- code: `
680
- type MyType = {
681
- readonly filter: () => Record<string, string>;
682
- };
683
-
684
- const myValue: MyType = {
685
- filter: () => ({ foo: "bar" }),
686
- } as const;
687
-
688
- const foo: Readonly<Record<string, string>> = myValue.filter();
689
- `,
680
+ code: dedent`
681
+ type MyType = {
682
+ readonly filter: () => Record<string, string>;
683
+ };
684
+
685
+ const myValue: MyType = {
686
+ filter: () => ({ foo: "bar" }),
687
+ } as const;
688
+
689
+ const foo: Readonly<Record<string, string>> = myValue.filter();
690
+ `,
690
691
  errors: [
691
692
  {
692
693
  messageId: 'errorStringGeneric',
@@ -697,17 +698,17 @@ ruleTester.run(
697
698
  // mutable function array value -> readonly.
698
699
  {
699
700
  filename: 'file.ts',
700
- code: `
701
- type MyType = {
702
- readonly filter: () => string[];
703
- };
704
-
705
- const myValue: MyType = {
706
- filter: () => (["bar"]),
707
- } as const;
708
-
709
- const foo: readonly string[] = myValue.filter();
710
- `,
701
+ code: dedent`
702
+ type MyType = {
703
+ readonly filter: () => string[];
704
+ };
705
+
706
+ const myValue: MyType = {
707
+ filter: () => (["bar"]),
708
+ } as const;
709
+
710
+ const foo: readonly string[] = myValue.filter();
711
+ `,
711
712
  errors: [
712
713
  {
713
714
  messageId: 'errorStringGeneric',
@@ -717,18 +718,18 @@ ruleTester.run(
717
718
  },
718
719
  {
719
720
  filename: 'file.ts',
720
- code: `
721
- type MyReadonlyType = { readonly a: string };
722
- type MyMutableType = { a: string };
723
-
724
- const mutableVal: MyMutableType = { a: "" };
725
- const readonlyArrayOfMutable: readonly MyMutableType[] = [mutableVal] as const;
726
-
727
- const shouldBeImmutable: readonly MyReadonlyType[] =
728
- readonlyArrayOfMutable.concat({
729
- a: "",
730
- });
731
- `,
721
+ code: dedent`
722
+ type MyReadonlyType = { readonly a: string };
723
+ type MyMutableType = { a: string };
724
+
725
+ const mutableVal: MyMutableType = { a: "" };
726
+ const readonlyArrayOfMutable: readonly MyMutableType[] = [mutableVal] as const;
727
+
728
+ const shouldBeImmutable: readonly MyReadonlyType[] =
729
+ readonlyArrayOfMutable.concat({
730
+ a: "",
731
+ });
732
+ `,
732
733
  errors: [
733
734
  {
734
735
  messageId: 'errorStringGeneric',
@@ -739,15 +740,15 @@ ruleTester.run(
739
740
  // yield expression (generator)
740
741
  {
741
742
  filename: 'file.ts',
742
- code: `
743
- type MutableA = { a: string };
744
- type ReadonlyA = { readonly a: string };
745
-
746
- export function* mySaga(): Generator<ReadonlyA> {
747
- const foo: MutableA = { a: "" };
748
- yield foo;
749
- }
750
- `,
743
+ code: dedent`
744
+ type MutableA = { a: string };
745
+ type ReadonlyA = { readonly a: string };
746
+
747
+ export function* mySaga(): Generator<ReadonlyA> {
748
+ const foo: MutableA = { a: "" };
749
+ yield foo;
750
+ }
751
+ `,
751
752
  errors: [
752
753
  {
753
754
  messageId: 'errorStringGeneric',
@@ -758,66 +759,66 @@ ruleTester.run(
758
759
  // deep(ish) type
759
760
  {
760
761
  filename: 'file.ts',
761
- code: `
762
- type A = {
763
- a: string;
764
- };
765
-
766
- type B = {
767
- readonly a: A;
768
- };
769
-
770
- type C = {
771
- readonly b: B;
772
- };
773
-
774
- type D = {
775
- readonly c: C;
776
- };
777
-
778
- type E = {
779
- readonly d: D;
780
- };
781
-
782
- type F = {
783
- readonly e: E;
784
- };
785
-
786
- type G = {
787
- readonly f: F;
788
- };
789
-
790
- type A2 = {
791
- readonly a: string;
792
- };
793
-
794
- type B2 = {
795
- readonly a: A2;
796
- };
797
-
798
- type C2 = {
799
- readonly b: B2;
800
- };
801
-
802
- type D2 = {
803
- readonly c: C2;
804
- };
805
-
806
- type E2 = {
807
- readonly d: D2;
808
- };
809
-
810
- type F2 = {
811
- readonly e: E2;
812
- };
813
-
814
- type G2 = {
815
- readonly f: F2;
816
- };
817
-
818
- declare const g: G;
819
- export const g2: G2 = g;
820
- `,
762
+ code: dedent`
763
+ type A = {
764
+ a: string;
765
+ };
766
+
767
+ type B = {
768
+ readonly a: A;
769
+ };
770
+
771
+ type C = {
772
+ readonly b: B;
773
+ };
774
+
775
+ type D = {
776
+ readonly c: C;
777
+ };
778
+
779
+ type E = {
780
+ readonly d: D;
781
+ };
782
+
783
+ type F = {
784
+ readonly e: E;
785
+ };
786
+
787
+ type G = {
788
+ readonly f: F;
789
+ };
790
+
791
+ type A2 = {
792
+ readonly a: string;
793
+ };
794
+
795
+ type B2 = {
796
+ readonly a: A2;
797
+ };
798
+
799
+ type C2 = {
800
+ readonly b: B2;
801
+ };
802
+
803
+ type D2 = {
804
+ readonly c: C2;
805
+ };
806
+
807
+ type E2 = {
808
+ readonly d: D2;
809
+ };
810
+
811
+ type F2 = {
812
+ readonly e: E2;
813
+ };
814
+
815
+ type G2 = {
816
+ readonly f: F2;
817
+ };
818
+
819
+ declare const g: G;
820
+ export const g2: G2 = g;
821
+ `,
821
822
  errors: [
822
823
  {
823
824
  messageId: 'errorStringGeneric',