Skip to content

Commit 4882d42

Browse files
feat(prefer-readonly-type): turn option "allowMutableReturnType" on by default
BREAKING CHANGE: allowMutableReturnType is now on by default re #153
1 parent 210e84e commit 4882d42

File tree

4 files changed

+273
-75
lines changed

4 files changed

+273
-75
lines changed

docs/rules/prefer-readonly-type.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ The default options:
106106
```ts
107107
{
108108
allowLocalMutation: false,
109-
allowMutableReturnType: false,
109+
allowMutableReturnType: true,
110110
checkImplicit: false,
111111
ignoreClass: false,
112112
ignoreInterface: false,

src/rules/prefer-readonly-type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const defaultOptions: Options = {
7474
ignoreInterface: false,
7575
ignoreCollections: false,
7676
allowLocalMutation: false,
77-
allowMutableReturnType: false,
77+
allowMutableReturnType: true,
7878
};
7979

8080
// The possible error messages.

tests/rules/prefer-readonly-type/ts/invalid.ts

Lines changed: 251 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,12 @@ const tests: ReadonlyArray<InvalidTestCase> = [
125125
}`,
126126
optionsSet: [[]],
127127
output: dedent`
128-
function foo(): ReadonlyArray<string> {
128+
function foo(): Array<string> {
129129
interface Foo {
130130
readonly bar: ReadonlyArray<string>
131131
}
132132
}`,
133133
errors: [
134-
{
135-
messageId: "type",
136-
type: "TSTypeReference",
137-
line: 1,
138-
column: 17,
139-
},
140134
{
141135
messageId: "type",
142136
type: "TSTypeReference",
@@ -155,18 +149,12 @@ const tests: ReadonlyArray<InvalidTestCase> = [
155149
}`,
156150
optionsSet: [[]],
157151
output: dedent`
158-
const foo = (): ReadonlyArray<string> => {
152+
const foo = (): Array<string> => {
159153
interface Foo {
160154
readonly bar: ReadonlyArray<string>
161155
}
162156
}`,
163157
errors: [
164-
{
165-
messageId: "type",
166-
type: "TSTypeReference",
167-
line: 1,
168-
column: 17,
169-
},
170158
{
171159
messageId: "type",
172160
type: "TSTypeReference",
@@ -175,38 +163,6 @@ const tests: ReadonlyArray<InvalidTestCase> = [
175163
},
176164
],
177165
},
178-
// Should fail on shorthand syntax Array type as return type.
179-
{
180-
code: dedent`
181-
function foo(): number[] {
182-
}`,
183-
optionsSet: [[]],
184-
output: dedent`
185-
function foo(): readonly number[] {
186-
}`,
187-
errors: [
188-
{
189-
messageId: "array",
190-
type: "TSArrayType",
191-
line: 1,
192-
column: 17,
193-
},
194-
],
195-
},
196-
// Should fail on shorthand syntax Array type as return type.
197-
{
198-
code: `const foo = (): number[] => {}`,
199-
optionsSet: [[]],
200-
output: `const foo = (): readonly number[] => {}`,
201-
errors: [
202-
{
203-
messageId: "array",
204-
type: "TSArrayType",
205-
line: 1,
206-
column: 17,
207-
},
208-
],
209-
},
210166
// Should fail inside function.
211167
{
212168
code: dedent`
@@ -331,7 +287,7 @@ const tests: ReadonlyArray<InvalidTestCase> = [
331287
readonly baz: ReadonlyArray<string>
332288
}
333289
): {
334-
readonly bar: ReadonlyArray<string>,
290+
readonly bar: Array<string>,
335291
readonly baz: ReadonlyArray<string>
336292
} {
337293
let foo: {
@@ -350,12 +306,6 @@ const tests: ReadonlyArray<InvalidTestCase> = [
350306
line: 3,
351307
column: 19,
352308
},
353-
{
354-
messageId: "type",
355-
type: "TSTypeReference",
356-
line: 7,
357-
column: 17,
358-
},
359309
{
360310
messageId: "type",
361311
type: "TSTypeReference",
@@ -852,6 +802,254 @@ const tests: ReadonlyArray<InvalidTestCase> = [
852802
},
853803
],
854804
},
805+
// Don't allow mutable return type.
806+
{
807+
code: dedent`
808+
function foo(...numbers: ReadonlyArray<number>): Array<number> {}
809+
function bar(...numbers: readonly number[]): number[] {}`,
810+
optionsSet: [[{ allowMutableReturnType: false }]],
811+
output: dedent`
812+
function foo(...numbers: ReadonlyArray<number>): ReadonlyArray<number> {}
813+
function bar(...numbers: readonly number[]): readonly number[] {}`,
814+
errors: [
815+
{
816+
messageId: "type",
817+
type: "TSTypeReference",
818+
line: 1,
819+
column: 50,
820+
},
821+
{
822+
messageId: "array",
823+
type: "TSArrayType",
824+
line: 2,
825+
column: 46,
826+
},
827+
],
828+
},
829+
// Don't allow mutable return type.
830+
{
831+
code: dedent`
832+
const foo = function(...numbers: ReadonlyArray<number>): Array<number> {}
833+
const bar = function(...numbers: readonly number[]): number[] {}`,
834+
optionsSet: [[{ allowMutableReturnType: false }]],
835+
output: dedent`
836+
const foo = function(...numbers: ReadonlyArray<number>): ReadonlyArray<number> {}
837+
const bar = function(...numbers: readonly number[]): readonly number[] {}`,
838+
errors: [
839+
{
840+
messageId: "type",
841+
type: "TSTypeReference",
842+
line: 1,
843+
column: 58,
844+
},
845+
{
846+
messageId: "array",
847+
type: "TSArrayType",
848+
line: 2,
849+
column: 54,
850+
},
851+
],
852+
},
853+
// Don't allow mutable return type.
854+
{
855+
code: dedent`
856+
const foo = (...numbers: ReadonlyArray<number>): Array<number> => {}
857+
const bar = (...numbers: readonly number[]): number[] => {}`,
858+
optionsSet: [[{ allowMutableReturnType: false }]],
859+
output: dedent`
860+
const foo = (...numbers: ReadonlyArray<number>): ReadonlyArray<number> => {}
861+
const bar = (...numbers: readonly number[]): readonly number[] => {}`,
862+
errors: [
863+
{
864+
messageId: "type",
865+
type: "TSTypeReference",
866+
line: 1,
867+
column: 50,
868+
},
869+
{
870+
messageId: "array",
871+
type: "TSArrayType",
872+
line: 2,
873+
column: 46,
874+
},
875+
],
876+
},
877+
// Don't allow mutable return type.
878+
{
879+
code: dedent`
880+
class Foo {
881+
foo(...numbers: ReadonlyArray<number>): Array<number> {
882+
}
883+
}
884+
class Bar {
885+
foo(...numbers: readonly number[]): number[] {
886+
}
887+
}`,
888+
optionsSet: [[{ allowMutableReturnType: false }]],
889+
output: dedent`
890+
class Foo {
891+
foo(...numbers: ReadonlyArray<number>): ReadonlyArray<number> {
892+
}
893+
}
894+
class Bar {
895+
foo(...numbers: readonly number[]): readonly number[] {
896+
}
897+
}`,
898+
errors: [
899+
{
900+
messageId: "type",
901+
type: "TSTypeReference",
902+
line: 2,
903+
column: 43,
904+
},
905+
{
906+
messageId: "array",
907+
type: "TSArrayType",
908+
line: 6,
909+
column: 39,
910+
},
911+
],
912+
},
913+
// Don't allow mutable return type with Type Arguments.
914+
{
915+
code: dedent`
916+
function foo(...numbers: ReadonlyArray<number>): Promise<Array<number>> {}
917+
function foo(...numbers: ReadonlyArray<number>): Promise<number[]> {}`,
918+
optionsSet: [[{ allowMutableReturnType: false }]],
919+
output: dedent`
920+
function foo(...numbers: ReadonlyArray<number>): Promise<ReadonlyArray<number>> {}
921+
function foo(...numbers: ReadonlyArray<number>): Promise<readonly number[]> {}`,
922+
errors: [
923+
{
924+
messageId: "type",
925+
type: "TSTypeReference",
926+
line: 1,
927+
column: 58,
928+
},
929+
{
930+
messageId: "array",
931+
type: "TSArrayType",
932+
line: 2,
933+
column: 58,
934+
},
935+
],
936+
},
937+
// Don't allow mutable return type with deep Type Arguments.
938+
{
939+
code: dedent`
940+
type Foo<T> = { readonly x: T; };
941+
function foo(...numbers: ReadonlyArray<number>): Promise<Foo<Array<number>>> {}
942+
function foo(...numbers: ReadonlyArray<number>): Promise<Foo<number[]>> {}`,
943+
optionsSet: [[{ allowMutableReturnType: false }]],
944+
output: dedent`
945+
type Foo<T> = { readonly x: T; };
946+
function foo(...numbers: ReadonlyArray<number>): Promise<Foo<ReadonlyArray<number>>> {}
947+
function foo(...numbers: ReadonlyArray<number>): Promise<Foo<readonly number[]>> {}`,
948+
errors: [
949+
{
950+
messageId: "type",
951+
type: "TSTypeReference",
952+
line: 2,
953+
column: 62,
954+
},
955+
{
956+
messageId: "array",
957+
type: "TSArrayType",
958+
line: 3,
959+
column: 62,
960+
},
961+
],
962+
},
963+
// Don't allow mutable return type with Type Arguments in a tuple.
964+
{
965+
code: dedent`
966+
function foo(...numbers: ReadonlyArray<number>): readonly [number, Array<number>, number] {}
967+
function foo(...numbers: ReadonlyArray<number>): readonly [number, number[], number] {}`,
968+
optionsSet: [[{ allowMutableReturnType: false }]],
969+
output: dedent`
970+
function foo(...numbers: ReadonlyArray<number>): readonly [number, ReadonlyArray<number>, number] {}
971+
function foo(...numbers: ReadonlyArray<number>): readonly [number, readonly number[], number] {}`,
972+
errors: [
973+
{
974+
messageId: "type",
975+
type: "TSTypeReference",
976+
line: 1,
977+
column: 68,
978+
},
979+
{
980+
messageId: "array",
981+
type: "TSArrayType",
982+
line: 2,
983+
column: 68,
984+
},
985+
],
986+
},
987+
// Don't allow mutable return type with Type Arguments Union.
988+
{
989+
code: dedent`
990+
function foo(...numbers: ReadonlyArray<number>): { readonly a: Array<number> } | { readonly b: string[] } {}`,
991+
optionsSet: [[{ allowMutableReturnType: false }]],
992+
output: dedent`
993+
function foo(...numbers: ReadonlyArray<number>): { readonly a: ReadonlyArray<number> } | { readonly b: readonly string[] } {}`,
994+
errors: [
995+
{
996+
messageId: "type",
997+
type: "TSTypeReference",
998+
line: 1,
999+
column: 64,
1000+
},
1001+
{
1002+
messageId: "array",
1003+
type: "TSArrayType",
1004+
line: 1,
1005+
column: 96,
1006+
},
1007+
],
1008+
},
1009+
// Don't allow mutable return type with Type Arguments Intersection.
1010+
{
1011+
code: dedent`
1012+
function foo(...numbers: ReadonlyArray<number>): { readonly a: Array<number> } & { readonly b: string[] } {}`,
1013+
optionsSet: [[{ allowMutableReturnType: false }]],
1014+
output: dedent`
1015+
function foo(...numbers: ReadonlyArray<number>): { readonly a: ReadonlyArray<number> } & { readonly b: readonly string[] } {}`,
1016+
errors: [
1017+
{
1018+
messageId: "type",
1019+
type: "TSTypeReference",
1020+
line: 1,
1021+
column: 64,
1022+
},
1023+
{
1024+
messageId: "array",
1025+
type: "TSArrayType",
1026+
line: 1,
1027+
column: 96,
1028+
},
1029+
],
1030+
},
1031+
// Don't allow mutable return type with Type Arguments Conditional.
1032+
{
1033+
code: dedent`
1034+
function foo<T>(x: T): T extends Array<number> ? string : number[] {}`,
1035+
optionsSet: [[{ allowMutableReturnType: false }]],
1036+
output: dedent`
1037+
function foo<T>(x: T): T extends ReadonlyArray<number> ? string : readonly number[] {}`,
1038+
errors: [
1039+
{
1040+
messageId: "type",
1041+
type: "TSTypeReference",
1042+
line: 1,
1043+
column: 34,
1044+
},
1045+
{
1046+
messageId: "array",
1047+
type: "TSArrayType",
1048+
line: 1,
1049+
column: 59,
1050+
},
1051+
],
1052+
},
8551053
];
8561054

8571055
export default tests;

0 commit comments

Comments
 (0)