From 581048b97a3d7059bd4d5b05e994ab2df38870b9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Dec 2020 12:12:28 -1000 Subject: [PATCH] Use strictSubtypeRelation only as tiebreaker --- src/compiler/checker.ts | 4 ++-- ...arrayLiteralWithMultipleBestCommonTypes.types | 4 ++-- .../contextualTypingArrayOfLambdas.types | 4 ++-- .../functionWithMultipleReturnStatements2.types | 2 +- ...subtypesOfTypeParameterWithConstraints2.types | 8 ++++---- .../reference/unionTypeReduction2.errors.txt | 5 ++++- .../reference/unionTypeReduction2.symbols | 8 ++++---- .../reference/unionTypeReduction2.types | 16 ++++++++-------- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3309f83a76..f0e47eaed97 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13154,7 +13154,7 @@ namespace ts { } } count++; - if (isTypeRelatedTo(source, target, strictSubtypeRelation) && ( + if (isTypeSubtypeOf(source, target) && (!isTypeSubtypeOf(target, source) || isTypeRelatedTo(source, target, strictSubtypeRelation)) && ( !(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) || !(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) || isTypeDerivedFrom(source, target))) { @@ -16231,7 +16231,7 @@ namespace ts { return Ternary.False; } - const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && (checkMode & SignatureCheckMode.StrictArity || isStrictSignature(target)); + const strictVariance = !(checkMode & SignatureCheckMode.Callback) && (checkMode & SignatureCheckMode.StrictArity || strictFunctionTypes && isStrictSignature(target)); let result = Ternary.True; const sourceThisType = getThisTypeOfSignature(source); diff --git a/tests/baselines/reference/arrayLiteralWithMultipleBestCommonTypes.types b/tests/baselines/reference/arrayLiteralWithMultipleBestCommonTypes.types index a7553fd5cd5..6572893f900 100644 --- a/tests/baselines/reference/arrayLiteralWithMultipleBestCommonTypes.types +++ b/tests/baselines/reference/arrayLiteralWithMultipleBestCommonTypes.types @@ -36,8 +36,8 @@ var cs = [a, b, c]; // { x: number; y?: number };[] >c : { x: number; a?: number; } var ds = [(x: Object) => 1, (x: string) => 2]; // { (x:Object) => number }[] ->ds : ((x: Object) => number)[] ->[(x: Object) => 1, (x: string) => 2] : ((x: Object) => number)[] +>ds : ((x: string) => number)[] +>[(x: Object) => 1, (x: string) => 2] : ((x: string) => number)[] >(x: Object) => 1 : (x: Object) => number >x : Object >1 : 1 diff --git a/tests/baselines/reference/contextualTypingArrayOfLambdas.types b/tests/baselines/reference/contextualTypingArrayOfLambdas.types index 36b8aaa715f..ffe589c0929 100644 --- a/tests/baselines/reference/contextualTypingArrayOfLambdas.types +++ b/tests/baselines/reference/contextualTypingArrayOfLambdas.types @@ -23,8 +23,8 @@ class C extends A { } var xs = [(x: A) => { }, (x: B) => { }, (x: C) => { }]; ->xs : ((x: A) => void)[] ->[(x: A) => { }, (x: B) => { }, (x: C) => { }] : ((x: A) => void)[] +>xs : (((x: B) => void) | ((x: C) => void))[] +>[(x: A) => { }, (x: B) => { }, (x: C) => { }] : (((x: B) => void) | ((x: C) => void))[] >(x: A) => { } : (x: A) => void >x : A >(x: B) => { } : (x: B) => void diff --git a/tests/baselines/reference/functionWithMultipleReturnStatements2.types b/tests/baselines/reference/functionWithMultipleReturnStatements2.types index f528ad04aae..3a0144447c0 100644 --- a/tests/baselines/reference/functionWithMultipleReturnStatements2.types +++ b/tests/baselines/reference/functionWithMultipleReturnStatements2.types @@ -58,7 +58,7 @@ function f4() { } function f5() { ->f5 : () => Object | 1 +>f5 : () => Object return 1; >1 : 1 diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types index dc3f90fa545..daf700b06f2 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types @@ -566,16 +566,16 @@ function f20(x: T) { >x : T var r19 = true ? new Object() : x; // ok ->r19 : Object | T ->true ? new Object() : x : Object | T +>r19 : Object +>true ? new Object() : x : Object >true : true >new Object() : Object >Object : ObjectConstructor >x : T var r19 = true ? x : new Object(); // ok ->r19 : Object | T ->true ? x : new Object() : Object | T +>r19 : Object +>true ? x : new Object() : Object >true : true >x : T >new Object() : Object diff --git a/tests/baselines/reference/unionTypeReduction2.errors.txt b/tests/baselines/reference/unionTypeReduction2.errors.txt index 74567f8808b..d62d7c187ba 100644 --- a/tests/baselines/reference/unionTypeReduction2.errors.txt +++ b/tests/baselines/reference/unionTypeReduction2.errors.txt @@ -1,7 +1,8 @@ tests/cases/conformance/types/union/unionTypeReduction2.ts(33,5): error TS2554: Expected 1 arguments, but got 0. +tests/cases/conformance/types/union/unionTypeReduction2.ts(49,9): error TS2554: Expected 0 arguments, but got 1. -==== tests/cases/conformance/types/union/unionTypeReduction2.ts (1 errors) ==== +==== tests/cases/conformance/types/union/unionTypeReduction2.ts (2 errors) ==== function f1(x: { f(): void }, y: { f(x?: string): void }) { let z = !!true ? x : y; // { f(x?: string): void } z.f(); @@ -54,6 +55,8 @@ tests/cases/conformance/types/union/unionTypeReduction2.ts(33,5): error TS2554: let z = !!true ? a : b; // A | B z.f(); z.f('hello'); + ~~~~~~~ +!!! error TS2554: Expected 0 arguments, but got 1. } // Repro from #35414 diff --git a/tests/baselines/reference/unionTypeReduction2.symbols b/tests/baselines/reference/unionTypeReduction2.symbols index 0faf0055279..92d412cf129 100644 --- a/tests/baselines/reference/unionTypeReduction2.symbols +++ b/tests/baselines/reference/unionTypeReduction2.symbols @@ -154,14 +154,14 @@ function f11(a: A, b: B) { >b : Symbol(b, Decl(unionTypeReduction2.ts, 45, 18)) z.f(); ->z.f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10), Decl(unionTypeReduction2.ts, 40, 10)) +>z.f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10)) >z : Symbol(z, Decl(unionTypeReduction2.ts, 46, 7)) ->f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10), Decl(unionTypeReduction2.ts, 40, 10)) +>f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10)) z.f('hello'); ->z.f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10), Decl(unionTypeReduction2.ts, 40, 10)) +>z.f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10)) >z : Symbol(z, Decl(unionTypeReduction2.ts, 46, 7)) ->f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10), Decl(unionTypeReduction2.ts, 40, 10)) +>f : Symbol(f, Decl(unionTypeReduction2.ts, 36, 10)) } // Repro from #35414 diff --git a/tests/baselines/reference/unionTypeReduction2.types b/tests/baselines/reference/unionTypeReduction2.types index 740ee289100..3b0ac20beea 100644 --- a/tests/baselines/reference/unionTypeReduction2.types +++ b/tests/baselines/reference/unionTypeReduction2.types @@ -189,8 +189,8 @@ function f11(a: A, b: B) { >b : B let z = !!true ? a : b; // A | B ->z : A | B ->!!true ? a : b : A | B +>z : A +>!!true ? a : b : A >!!true : true >!true : false >true : true @@ -199,15 +199,15 @@ function f11(a: A, b: B) { z.f(); >z.f() : void ->z.f : ((x?: string | undefined) => void) | (() => void) ->z : A | B ->f : ((x?: string | undefined) => void) | (() => void) +>z.f : () => void +>z : A +>f : () => void z.f('hello'); >z.f('hello') : void ->z.f : ((x?: string | undefined) => void) | (() => void) ->z : A | B ->f : ((x?: string | undefined) => void) | (() => void) +>z.f : () => void +>z : A +>f : () => void >'hello' : "hello" }