@@ -241,43 +241,6 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
241
241
* Assignment expressions
242
242
*/
243
243
// TODO
244
- /**
245
- * Arrow functions
246
- */
247
- // Arrow function (compact form) (readonly -> readonly)
248
- {
249
- filename : "file.ts" ,
250
- code : `
251
- type ReadonlyA = { readonly a: string };
252
- const ro: ReadonlyA = { a: "" } as const;
253
- const func = (): ReadonlyA => ro;
254
- ` ,
255
- } ,
256
- // Arrow function (compact form) (object literal -> readonly)
257
- {
258
- filename : "file.ts" ,
259
- code : `
260
- type ReadonlyA = { readonly a: string };
261
- const func = (): ReadonlyA => ({ a: "" } as const);
262
- ` ,
263
- } ,
264
- // Arrow function (compact form) (object literal -> mutable)
265
- {
266
- filename : "file.ts" ,
267
- code : `
268
- type MutableA = { a: string };
269
- const func = (): MutableA => { a: "" };
270
- ` ,
271
- } ,
272
- // Arrow function (compact form) (mutable -> mutable)
273
- {
274
- filename : "file.ts" ,
275
- code : `
276
- type MutableA = { a: string };
277
- const ro: MutableA = { a: "" };
278
- const func = (): MutableA => ro;
279
- ` ,
280
- } ,
281
244
// Array safe mutable to readonly assignment with chained array operations.
282
245
{
283
246
filename : "file.ts" ,
@@ -335,68 +298,6 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
335
298
const nextArray: readonly string[] = fooArray.slice();
336
299
` ,
337
300
} ,
338
- /**
339
- * type assertions
340
- */
341
- // readonly -> readonly
342
- {
343
- filename : "file.ts" ,
344
- code : `
345
- type ReadonlyA = { readonly a: string };
346
- const ro: ReadonlyA = { a: "" } as const;
347
- const mut = ro as ReadonlyA;
348
- ` ,
349
- } ,
350
- // mutable -> mutable
351
- {
352
- filename : "file.ts" ,
353
- code : `
354
- type MutableA = { a: string };
355
- const ro: MutableA = { a: "" };
356
- const mut = ro as MutableA;
357
- ` ,
358
- } ,
359
- // readonly -> readonly
360
- {
361
- filename : "file.ts" ,
362
- code : `
363
- type ReadonlyA = { readonly a: string };
364
- const ro: ReadonlyA = { a: "" } as const;
365
- const mut = <ReadonlyA>ro;
366
- ` ,
367
- } ,
368
- // mutable -> mutable
369
- {
370
- filename : "file.ts" ,
371
- code : `
372
- type MutableA = { a: string };
373
- const ro: MutableA = { a: "" };
374
- const mut = <MutableA>ro;
375
- ` ,
376
- } ,
377
- // as const
378
- {
379
- filename : "file.ts" ,
380
- code : `
381
- type ReadonlyA = { readonly a: string };
382
- const ro: ReadonlyA = { a: "" } as const;
383
- ` ,
384
- } ,
385
- // <const>
386
- {
387
- filename : "file.ts" ,
388
- code : `
389
- type ReadonlyA = { readonly a: string };
390
- const ro: ReadonlyA = <const>{ a: "" };
391
- ` ,
392
- } ,
393
- // as unknown
394
- {
395
- filename : "file.ts" ,
396
- code : `
397
- const foo = [{ key: -1, label: "", value: "" }] as unknown;
398
- ` ,
399
- } ,
400
301
/**
401
302
* Return statement
402
303
*/
@@ -639,6 +540,34 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
639
540
const bar: Bar<string> = foo;
640
541
` ,
641
542
} ,
543
+ // Return empty array literal from function that is declared to return empty tuple.
544
+ {
545
+ filename : "file.ts" ,
546
+ code : `
547
+ const foo = (): readonly [] => {
548
+ return [];
549
+ };
550
+ ` ,
551
+ } ,
552
+ // https://github.com/danielnixon/eslint-plugin-total-functions/issues/741
553
+ {
554
+ filename : "file.ts" ,
555
+ code : `
556
+ type Foo<U> = {
557
+ b?: Foo<Foo<U>>;
558
+ };
559
+
560
+ const takesAFoo = <U>(foo: Foo<U>): void => {
561
+ return undefined;
562
+ }
563
+
564
+ let foo: Foo<unknown> = { b: {} };
565
+
566
+ foo.b = foo;
567
+
568
+ takesAFoo(foo);
569
+ ` ,
570
+ } ,
642
571
] ,
643
572
invalid : [
644
573
// initalization using mutable (literal) -> readonly
@@ -676,41 +605,6 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
676
605
// },
677
606
// ],
678
607
// },
679
- /**
680
- * type assertions
681
- */
682
- // mutable -> readonly
683
- {
684
- filename : "file.ts" ,
685
- code : `
686
- type MutableA = { a: string };
687
- type ReadonlyA = { readonly a: string };
688
- const ro: MutableA = { a: "" };
689
- const mut = <ReadonlyA>ro;
690
- ` ,
691
- errors : [
692
- {
693
- messageId : "errorStringTSTypeAssertion" ,
694
- type : AST_NODE_TYPES . TSTypeAssertion ,
695
- } ,
696
- ] ,
697
- } ,
698
- // mutable -> readonly
699
- {
700
- filename : "file.ts" ,
701
- code : `
702
- type MutableA = { a: string };
703
- type ReadonlyA = { readonly a: string };
704
- const ro: MutableA = { a: "" };
705
- const mut = ro as ReadonlyA;
706
- ` ,
707
- errors : [
708
- {
709
- messageId : "errorStringTSAsExpression" ,
710
- type : AST_NODE_TYPES . TSAsExpression ,
711
- } ,
712
- ] ,
713
- } ,
714
608
// mutable -> readonly
715
609
{
716
610
filename : "file.ts" ,
@@ -749,24 +643,6 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
749
643
} ,
750
644
] ,
751
645
} ,
752
- // mutable function return -> readonly function return (as part of intersection with object).
753
- {
754
- filename : "file.ts" ,
755
- code : `
756
- type RandomObject = { readonly b?: string };
757
- type MutableA = RandomObject & (() => { a: string });
758
- type ReadonlyA = RandomObject & (() => { readonly a: string });
759
-
760
- const ma: MutableA = () => ({ a: "" });
761
- const ra: ReadonlyA = ma;
762
- ` ,
763
- errors : [
764
- {
765
- messageId : "errorStringVariableDeclaration" ,
766
- type : AST_NODE_TYPES . VariableDeclaration ,
767
- } ,
768
- ] ,
769
- } ,
770
646
// mutable object prop -> readonly object prop (as part of intersection with non-object).
771
647
{
772
648
filename : "file.ts" ,
@@ -784,51 +660,6 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
784
660
} ,
785
661
] ,
786
662
} ,
787
- // Return empty mutable array from function that is declared to return empty tuple.
788
- {
789
- filename : "file.ts" ,
790
- code : `
791
- const foo = (): readonly [] => {
792
- return [];
793
- };
794
- ` ,
795
- errors : [
796
- {
797
- messageId : "errorStringArrowFunctionExpression" ,
798
- type : AST_NODE_TYPES . ReturnStatement ,
799
- } ,
800
- ] ,
801
- } ,
802
- // mutable function return -> readonly function return (multiple call signatures).
803
- {
804
- filename : "file.ts" ,
805
- code : `
806
- type MutableA = { a: string };
807
- type ReadonlyA = { readonly a: string };
808
-
809
- interface MutableFunc {
810
- (b: number): MutableA;
811
- (b: string): MutableA;
812
- }
813
-
814
- interface ReadonlyFunc {
815
- (b: number): ReadonlyA;
816
- (b: string): ReadonlyA;
817
- }
818
-
819
- const mf: MutableFunc = (b: number | string): MutableA => {
820
- return { a: "" };
821
- };
822
-
823
- const rf: ReadonlyFunc = mf;
824
- ` ,
825
- errors : [
826
- {
827
- messageId : "errorStringVariableDeclaration" ,
828
- type : AST_NODE_TYPES . VariableDeclaration ,
829
- } ,
830
- ] ,
831
- } ,
832
663
// mutable function value -> readonly.
833
664
{
834
665
filename : "file.ts" ,
@@ -920,55 +751,55 @@ ruleTester.run("no-unsafe-mutable-readonly-assignment", rule, {
920
751
};
921
752
922
753
type B = {
923
- a: A;
754
+ readonly a: A;
924
755
};
925
756
926
757
type C = {
927
- b: B;
758
+ readonly b: B;
928
759
};
929
760
930
761
type D = {
931
- c: C;
762
+ readonly c: C;
932
763
};
933
764
934
765
type E = {
935
- d: D;
766
+ readonly d: D;
936
767
};
937
768
938
769
type F = {
939
- e: E;
770
+ readonly e: E;
940
771
};
941
772
942
773
type G = {
943
- f: F;
774
+ readonly f: F;
944
775
};
945
776
946
777
type A2 = {
947
778
readonly a: string;
948
779
};
949
780
950
781
type B2 = {
951
- a: A2;
782
+ readonly a: A2;
952
783
};
953
784
954
785
type C2 = {
955
- b: B2;
786
+ readonly b: B2;
956
787
};
957
788
958
789
type D2 = {
959
- c: C2;
790
+ readonly c: C2;
960
791
};
961
792
962
793
type E2 = {
963
- d: D2;
794
+ readonly d: D2;
964
795
};
965
796
966
797
type F2 = {
967
- e: E2;
798
+ readonly e: E2;
968
799
};
969
800
970
801
type G2 = {
971
- f: F2;
802
+ readonly f: F2;
972
803
};
973
804
974
805
declare const g: G;
0 commit comments