@@ -329,6 +329,23 @@ let unknownValue: unknown;
329
329
unknownValue?.();
330
330
` ,
331
331
'const foo = [1, 2, 3][0];' ,
332
+ `
333
+ declare const foo: { bar?: { baz: { c: string } } } | null;
334
+ foo?.bar?.baz;
335
+ ` ,
336
+ `
337
+ foo?.bar?.baz?.qux;
338
+ ` ,
339
+ `
340
+ declare const foo: { bar: { baz: string } };
341
+ foo.bar.qux?.();
342
+ ` ,
343
+ `
344
+ type Foo = { baz: number } | null;
345
+ type Bar = { baz: null | string | { qux: string } };
346
+ declare const foo: { fooOrBar: Foo | Bar } | null;
347
+ foo?.fooOrBar?.baz?.qux;
348
+ ` ,
332
349
] ,
333
350
invalid : [
334
351
// Ensure that it's checking in all the right places
@@ -836,5 +853,216 @@ x.a;
836
853
} ,
837
854
] ,
838
855
} ,
856
+ {
857
+ code : `
858
+ declare const foo: { bar: { baz: { c: string } } } | null;
859
+ foo?.bar?.baz;
860
+ ` ,
861
+ output : `
862
+ declare const foo: { bar: { baz: { c: string } } } | null;
863
+ foo?.bar.baz;
864
+ ` ,
865
+ errors : [
866
+ {
867
+ messageId : 'neverOptionalChain' ,
868
+ line : 3 ,
869
+ endLine : 3 ,
870
+ column : 9 ,
871
+ endColumn : 11 ,
872
+ } ,
873
+ ] ,
874
+ } ,
875
+ {
876
+ code : `
877
+ declare const foo: { bar?: { baz: { qux: string } } } | null;
878
+ foo?.bar?.baz?.qux;
879
+ ` ,
880
+ output : `
881
+ declare const foo: { bar?: { baz: { qux: string } } } | null;
882
+ foo?.bar?.baz.qux;
883
+ ` ,
884
+ errors : [
885
+ {
886
+ messageId : 'neverOptionalChain' ,
887
+ line : 3 ,
888
+ endLine : 3 ,
889
+ column : 14 ,
890
+ endColumn : 16 ,
891
+ } ,
892
+ ] ,
893
+ } ,
894
+ {
895
+ code : `
896
+ declare const foo: { bar: { baz: { qux?: () => {} } } } | null;
897
+ foo?.bar?.baz?.qux?.();
898
+ ` ,
899
+ output : `
900
+ declare const foo: { bar: { baz: { qux?: () => {} } } } | null;
901
+ foo?.bar.baz.qux?.();
902
+ ` ,
903
+ errors : [
904
+ {
905
+ messageId : 'neverOptionalChain' ,
906
+ line : 3 ,
907
+ endLine : 3 ,
908
+ column : 9 ,
909
+ endColumn : 11 ,
910
+ } ,
911
+ {
912
+ messageId : 'neverOptionalChain' ,
913
+ line : 3 ,
914
+ endLine : 3 ,
915
+ column : 14 ,
916
+ endColumn : 16 ,
917
+ } ,
918
+ ] ,
919
+ } ,
920
+ {
921
+ code : `
922
+ declare const foo: { bar: { baz: { qux: () => {} } } } | null;
923
+ foo?.bar?.baz?.qux?.();
924
+ ` ,
925
+ output : `
926
+ declare const foo: { bar: { baz: { qux: () => {} } } } | null;
927
+ foo?.bar.baz.qux();
928
+ ` ,
929
+ errors : [
930
+ {
931
+ messageId : 'neverOptionalChain' ,
932
+ line : 3 ,
933
+ endLine : 3 ,
934
+ column : 9 ,
935
+ endColumn : 11 ,
936
+ } ,
937
+ {
938
+ messageId : 'neverOptionalChain' ,
939
+ line : 3 ,
940
+ endLine : 3 ,
941
+ column : 14 ,
942
+ endColumn : 16 ,
943
+ } ,
944
+ {
945
+ messageId : 'neverOptionalChain' ,
946
+ line : 3 ,
947
+ endLine : 3 ,
948
+ column : 19 ,
949
+ endColumn : 21 ,
950
+ } ,
951
+ ] ,
952
+ } ,
953
+ {
954
+ code : `
955
+ type baz = () => { qux: () => {} };
956
+ declare const foo: { bar: { baz: baz } } | null;
957
+ foo?.bar?.baz?.().qux?.();
958
+ ` ,
959
+ output : `
960
+ type baz = () => { qux: () => {} };
961
+ declare const foo: { bar: { baz: baz } } | null;
962
+ foo?.bar.baz().qux();
963
+ ` ,
964
+ errors : [
965
+ {
966
+ messageId : 'neverOptionalChain' ,
967
+ line : 4 ,
968
+ endLine : 4 ,
969
+ column : 9 ,
970
+ endColumn : 11 ,
971
+ } ,
972
+ {
973
+ messageId : 'neverOptionalChain' ,
974
+ line : 4 ,
975
+ endLine : 4 ,
976
+ column : 14 ,
977
+ endColumn : 16 ,
978
+ } ,
979
+ {
980
+ messageId : 'neverOptionalChain' ,
981
+ line : 4 ,
982
+ endLine : 4 ,
983
+ column : 22 ,
984
+ endColumn : 24 ,
985
+ } ,
986
+ ] ,
987
+ } ,
988
+ {
989
+ code : `
990
+ type baz = null | (() => { qux: () => {} });
991
+ declare const foo: { bar: { baz: baz } } | null;
992
+ foo?.bar?.baz?.().qux?.();
993
+ ` ,
994
+ output : `
995
+ type baz = null | (() => { qux: () => {} });
996
+ declare const foo: { bar: { baz: baz } } | null;
997
+ foo?.bar.baz?.().qux();
998
+ ` ,
999
+ errors : [
1000
+ {
1001
+ messageId : 'neverOptionalChain' ,
1002
+ line : 4 ,
1003
+ endLine : 4 ,
1004
+ column : 9 ,
1005
+ endColumn : 11 ,
1006
+ } ,
1007
+ {
1008
+ messageId : 'neverOptionalChain' ,
1009
+ line : 4 ,
1010
+ endLine : 4 ,
1011
+ column : 22 ,
1012
+ endColumn : 24 ,
1013
+ } ,
1014
+ ] ,
1015
+ } ,
1016
+ {
1017
+ code : `
1018
+ type baz = null | (() => { qux: () => {} } | null);
1019
+ declare const foo: { bar: { baz: baz } } | null;
1020
+ foo?.bar?.baz?.()?.qux?.();
1021
+ ` ,
1022
+ output : `
1023
+ type baz = null | (() => { qux: () => {} } | null);
1024
+ declare const foo: { bar: { baz: baz } } | null;
1025
+ foo?.bar.baz?.()?.qux();
1026
+ ` ,
1027
+ errors : [
1028
+ {
1029
+ messageId : 'neverOptionalChain' ,
1030
+ line : 4 ,
1031
+ endLine : 4 ,
1032
+ column : 9 ,
1033
+ endColumn : 11 ,
1034
+ } ,
1035
+ {
1036
+ messageId : 'neverOptionalChain' ,
1037
+ line : 4 ,
1038
+ endLine : 4 ,
1039
+ column : 23 ,
1040
+ endColumn : 25 ,
1041
+ } ,
1042
+ ] ,
1043
+ } ,
1044
+ {
1045
+ code : `
1046
+ type Foo = { baz: number };
1047
+ type Bar = { baz: null | string | { qux: string } };
1048
+ declare const foo: { fooOrBar: Foo | Bar } | null;
1049
+ foo?.fooOrBar?.baz?.qux;
1050
+ ` ,
1051
+ output : `
1052
+ type Foo = { baz: number };
1053
+ type Bar = { baz: null | string | { qux: string } };
1054
+ declare const foo: { fooOrBar: Foo | Bar } | null;
1055
+ foo?.fooOrBar.baz?.qux;
1056
+ ` ,
1057
+ errors : [
1058
+ {
1059
+ messageId : 'neverOptionalChain' ,
1060
+ line : 5 ,
1061
+ endLine : 5 ,
1062
+ column : 14 ,
1063
+ endColumn : 16 ,
1064
+ } ,
1065
+ ] ,
1066
+ } ,
839
1067
] ,
840
1068
} ) ;
0 commit comments