Skip to content

Commit 6c13712

Browse files
committed
Report generic rest parameters as unreliable variance positions
1 parent 3c42760 commit 6c13712

6 files changed

+294
-5
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12316,7 +12316,7 @@ namespace ts {
1231612316
target: Signature,
1231712317
ignoreReturnTypes: boolean): boolean {
1231812318
return compareSignaturesRelated(source, target, CallbackCheck.None, ignoreReturnTypes, /*reportErrors*/ false,
12319-
/*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
12319+
/*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False;
1232012320
}
1232112321

1232212322
type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void;
@@ -12339,7 +12339,8 @@ namespace ts {
1233912339
ignoreReturnTypes: boolean,
1234012340
reportErrors: boolean,
1234112341
errorReporter: ErrorReporter | undefined,
12342-
compareTypes: TypeComparer): Ternary {
12342+
compareTypes: TypeComparer,
12343+
reportUnreliableMarkers: TypeMapper | undefined): Ternary {
1234312344
// TODO (drosen): De-duplicate code between related functions.
1234412345
if (source === target) {
1234512346
return Ternary.True;
@@ -12362,6 +12363,9 @@ namespace ts {
1236212363
const sourceCount = getParameterCount(source);
1236312364
const sourceRestType = getNonArrayRestType(source);
1236412365
const targetRestType = getNonArrayRestType(target);
12366+
if (sourceRestType || targetRestType) {
12367+
void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
12368+
}
1236512369
if (sourceRestType && targetRestType && sourceCount !== targetCount) {
1236612370
// We're not able to relate misaligned complex rest parameters
1236712371
return Ternary.False;
@@ -12409,7 +12413,7 @@ namespace ts {
1240912413
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
1241012414
const related = callbacks ?
1241112415
// TODO: GH#18217 It will work if they're both `undefined`, but not if only one is
12412-
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
12416+
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes, reportUnreliableMarkers) :
1241312417
!callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
1241412418
if (!related) {
1241512419
if (reportErrors) {
@@ -14193,7 +14197,7 @@ namespace ts {
1419314197
*/
1419414198
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary {
1419514199
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
14196-
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
14200+
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo, reportUnreliableMarkers);
1419714201
}
1419814202

1419914203
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//// [aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts]
2+
// the type printback for every `test` below should be "y"
3+
4+
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
5+
type a = ExtendedMapper<any, any, [any]>;
6+
type b = ExtendedMapper<any, any, any[]>;
7+
type test = a extends b ? "y" : "n"
8+
let check: test = "y";
9+
10+
11+
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
12+
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
13+
);
14+
15+
type a1 = ExtendedMapper1<any, any, [any]>;
16+
type b1 = ExtendedMapper1<any, any, any[]>;
17+
type test1 = a1 extends b1 ? "y" : "n"
18+
let check1: test1 = "y";
19+
20+
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
21+
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
22+
);
23+
24+
type a2 = ExtendedMapper2<any, any, [any]>;
25+
type b2 = ExtendedMapper2<any, any, any[]>;
26+
type test2 = a2 extends b2 ? "y" : "n"
27+
let check2: test2 = "y";
28+
29+
type a3 = (name: string, mixed: any, args_0: any) => any
30+
type b3 = (name: string, mixed: any, ...args: any[]) => any
31+
32+
type test3 = a3 extends b3 ? "y" : "n"
33+
let check3: test3 = "y";
34+
35+
36+
//// [aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.js]
37+
"use strict";
38+
// the type printback for every `test` below should be "y"
39+
var check = "y";
40+
var check1 = "y";
41+
var check2 = "y";
42+
var check3 = "y";
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
=== tests/cases/compiler/aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts ===
2+
// the type printback for every `test` below should be "y"
3+
4+
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
5+
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
6+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 20))
7+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 34))
8+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 43))
9+
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 68))
10+
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 82))
11+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 20))
12+
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 105))
13+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 43))
14+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 34))
15+
16+
type a = ExtendedMapper<any, any, [any]>;
17+
>a : Symbol(a, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 134))
18+
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
19+
20+
type b = ExtendedMapper<any, any, any[]>;
21+
>b : Symbol(b, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 3, 41))
22+
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
23+
24+
type test = a extends b ? "y" : "n"
25+
>test : Symbol(test, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 4, 41))
26+
>a : Symbol(a, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 134))
27+
>b : Symbol(b, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 3, 41))
28+
29+
let check: test = "y";
30+
>check : Symbol(check, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 3))
31+
>test : Symbol(test, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 4, 41))
32+
33+
34+
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
35+
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
36+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 21))
37+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 35))
38+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 44))
39+
40+
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
41+
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 5))
42+
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 19))
43+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 21))
44+
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 42))
45+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 44))
46+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 35))
47+
48+
);
49+
50+
type a1 = ExtendedMapper1<any, any, [any]>;
51+
>a1 : Symbol(a1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 11, 2))
52+
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
53+
54+
type b1 = ExtendedMapper1<any, any, any[]>;
55+
>b1 : Symbol(b1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 13, 43))
56+
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
57+
58+
type test1 = a1 extends b1 ? "y" : "n"
59+
>test1 : Symbol(test1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 14, 43))
60+
>a1 : Symbol(a1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 11, 2))
61+
>b1 : Symbol(b1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 13, 43))
62+
63+
let check1: test1 = "y";
64+
>check1 : Symbol(check1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 3))
65+
>test1 : Symbol(test1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 14, 43))
66+
67+
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
68+
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
69+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 21))
70+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 35))
71+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 44))
72+
73+
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
74+
>x : Symbol(x, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 5))
75+
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 8))
76+
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 22))
77+
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 21))
78+
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 45))
79+
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 44))
80+
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 35))
81+
82+
);
83+
84+
type a2 = ExtendedMapper2<any, any, [any]>;
85+
>a2 : Symbol(a2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 20, 2))
86+
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
87+
88+
type b2 = ExtendedMapper2<any, any, any[]>;
89+
>b2 : Symbol(b2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 22, 43))
90+
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
91+
92+
type test2 = a2 extends b2 ? "y" : "n"
93+
>test2 : Symbol(test2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 23, 43))
94+
>a2 : Symbol(a2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 20, 2))
95+
>b2 : Symbol(b2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 22, 43))
96+
97+
let check2: test2 = "y";
98+
>check2 : Symbol(check2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 3))
99+
>test2 : Symbol(test2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 23, 43))
100+
101+
type a3 = (name: string, mixed: any, args_0: any) => any
102+
>a3 : Symbol(a3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 24))
103+
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 11))
104+
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 24))
105+
>args_0 : Symbol(args_0, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 36))
106+
107+
type b3 = (name: string, mixed: any, ...args: any[]) => any
108+
>b3 : Symbol(b3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 56))
109+
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 11))
110+
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 24))
111+
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 36))
112+
113+
type test3 = a3 extends b3 ? "y" : "n"
114+
>test3 : Symbol(test3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 59))
115+
>a3 : Symbol(a3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 24))
116+
>b3 : Symbol(b3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 56))
117+
118+
let check3: test3 = "y";
119+
>check3 : Symbol(check3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 31, 3))
120+
>test3 : Symbol(test3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 59))
121+
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
=== tests/cases/compiler/aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts ===
2+
// the type printback for every `test` below should be "y"
3+
4+
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
5+
>ExtendedMapper : ExtendedMapper<HandledInputT, OutputT, ArgsT>
6+
>name : string
7+
>mixed : HandledInputT
8+
>args : ArgsT
9+
10+
type a = ExtendedMapper<any, any, [any]>;
11+
>a : ExtendedMapper<any, any, [any]>
12+
13+
type b = ExtendedMapper<any, any, any[]>;
14+
>b : ExtendedMapper<any, any, any[]>
15+
16+
type test = a extends b ? "y" : "n"
17+
>test : "y"
18+
19+
let check: test = "y";
20+
>check : "y"
21+
>"y" : "y"
22+
23+
24+
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
25+
>ExtendedMapper1 : ExtendedMapper1<HandledInputT, OutputT, ArgsT>
26+
27+
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
28+
>name : string
29+
>mixed : HandledInputT
30+
>args : ArgsT
31+
32+
);
33+
34+
type a1 = ExtendedMapper1<any, any, [any]>;
35+
>a1 : ExtendedMapper1<any, any, [any]>
36+
37+
type b1 = ExtendedMapper1<any, any, any[]>;
38+
>b1 : ExtendedMapper1<any, any, any[]>
39+
40+
type test1 = a1 extends b1 ? "y" : "n"
41+
>test1 : "y"
42+
43+
let check1: test1 = "y";
44+
>check1 : "y"
45+
>"y" : "y"
46+
47+
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
48+
>ExtendedMapper2 : (name: string, mixed: HandledInputT, ...args: ArgsT) => OutputT
49+
50+
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
51+
>x : (name: string, mixed: HandledInputT, ...args: ArgsT) => OutputT
52+
>name : string
53+
>mixed : HandledInputT
54+
>args : ArgsT
55+
56+
);
57+
58+
type a2 = ExtendedMapper2<any, any, [any]>;
59+
>a2 : (name: string, mixed: any, args_0: any) => any
60+
61+
type b2 = ExtendedMapper2<any, any, any[]>;
62+
>b2 : (name: string, mixed: any, ...args: any[]) => any
63+
64+
type test2 = a2 extends b2 ? "y" : "n"
65+
>test2 : "y"
66+
67+
let check2: test2 = "y";
68+
>check2 : "y"
69+
>"y" : "y"
70+
71+
type a3 = (name: string, mixed: any, args_0: any) => any
72+
>a3 : a3
73+
>name : string
74+
>mixed : any
75+
>args_0 : any
76+
77+
type b3 = (name: string, mixed: any, ...args: any[]) => any
78+
>b3 : b3
79+
>name : string
80+
>mixed : any
81+
>args : any[]
82+
83+
type test3 = a3 extends b3 ? "y" : "n"
84+
>test3 : "y"
85+
86+
let check3: test3 = "y";
87+
>check3 : "y"
88+
>"y" : "y"
89+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// @strict: true
2+
// the type printback for every `test` below should be "y"
3+
4+
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
5+
type a = ExtendedMapper<any, any, [any]>;
6+
type b = ExtendedMapper<any, any, any[]>;
7+
type test = a extends b ? "y" : "n"
8+
let check: test = "y";
9+
10+
11+
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
12+
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
13+
);
14+
15+
type a1 = ExtendedMapper1<any, any, [any]>;
16+
type b1 = ExtendedMapper1<any, any, any[]>;
17+
type test1 = a1 extends b1 ? "y" : "n"
18+
let check1: test1 = "y";
19+
20+
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
21+
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
22+
);
23+
24+
type a2 = ExtendedMapper2<any, any, [any]>;
25+
type b2 = ExtendedMapper2<any, any, any[]>;
26+
type test2 = a2 extends b2 ? "y" : "n"
27+
let check2: test2 = "y";
28+
29+
type a3 = (name: string, mixed: any, args_0: any) => any
30+
type b3 = (name: string, mixed: any, ...args: any[]) => any
31+
32+
type test3 = a3 extends b3 ? "y" : "n"
33+
let check3: test3 = "y";

tests/cases/user/prettier/prettier

Submodule prettier updated 282 files

0 commit comments

Comments
 (0)