diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ec544ea0950d0..8e3040d3a3566 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14662,7 +14662,7 @@ namespace ts { inferFromTypes(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target)); inferFromTypes(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target)); } - else if (target.flags & TypeFlags.Conditional) { + else if (target.flags & TypeFlags.Conditional && !contravariant) { inferFromTypes(source, getTrueTypeFromConditionalType(target)); inferFromTypes(source, getFalseTypeFromConditionalType(target)); } diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.js b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.js new file mode 100644 index 0000000000000..e911b405074ca --- /dev/null +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.js @@ -0,0 +1,48 @@ +//// [overloadedConstructorFixesInferencesAppropriately.ts] +interface Box { + v: T; +} + +interface ErrorResult { + readonly error: true +} + +interface AsyncLoaderProps { + readonly asyncLoad: () => Box; + readonly children: (result: Exclude) => string; +} + +class AsyncLoader { + constructor(props: string, context: any); + constructor(props: AsyncLoaderProps); + constructor(...args: any[]) {} +} + +function load(): Box<{ success: true } | ErrorResult> { + return null as any; +} + +new AsyncLoader({ + asyncLoad: load, + children: result => result.success as any, +}); // should work fine + + +//// [overloadedConstructorFixesInferencesAppropriately.js] +"use strict"; +var AsyncLoader = /** @class */ (function () { + function AsyncLoader() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + } + return AsyncLoader; +}()); +function load() { + return null; +} +new AsyncLoader({ + asyncLoad: load, + children: function (result) { return result.success; } +}); // should work fine diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols new file mode 100644 index 0000000000000..dd6bb1909d3fe --- /dev/null +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols @@ -0,0 +1,76 @@ +=== tests/cases/compiler/overloadedConstructorFixesInferencesAppropriately.ts === +interface Box { +>Box : Symbol(Box, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 0)) +>T : Symbol(T, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 14)) + + v: T; +>v : Symbol(Box.v, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 18)) +>T : Symbol(T, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 14)) +} + +interface ErrorResult { +>ErrorResult : Symbol(ErrorResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 2, 1)) + + readonly error: true +>error : Symbol(ErrorResult.error, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 4, 23)) +} + +interface AsyncLoaderProps { +>AsyncLoaderProps : Symbol(AsyncLoaderProps, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 6, 1)) +>TResult : Symbol(TResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 8, 27)) + + readonly asyncLoad: () => Box; +>asyncLoad : Symbol(AsyncLoaderProps.asyncLoad, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 8, 48)) +>Box : Symbol(Box, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 0)) +>TResult : Symbol(TResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 8, 27)) + + readonly children: (result: Exclude) => string; +>children : Symbol(AsyncLoaderProps.children, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 9, 43)) +>result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 10, 24)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>TResult : Symbol(TResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 8, 27)) +>ErrorResult : Symbol(ErrorResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 2, 1)) +} + +class AsyncLoader { +>AsyncLoader : Symbol(AsyncLoader, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 11, 1)) +>TResult : Symbol(TResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 13, 18)) + + constructor(props: string, context: any); +>props : Symbol(props, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 14, 16)) +>context : Symbol(context, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 14, 30)) + + constructor(props: AsyncLoaderProps); +>props : Symbol(props, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 15, 16)) +>AsyncLoaderProps : Symbol(AsyncLoaderProps, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 6, 1)) +>TResult : Symbol(TResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 13, 18)) + + constructor(...args: any[]) {} +>args : Symbol(args, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 16, 16)) +} + +function load(): Box<{ success: true } | ErrorResult> { +>load : Symbol(load, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 17, 1)) +>Box : Symbol(Box, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 0, 0)) +>success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) +>ErrorResult : Symbol(ErrorResult, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 2, 1)) + + return null as any; +} + +new AsyncLoader({ +>AsyncLoader : Symbol(AsyncLoader, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 11, 1)) + + asyncLoad: load, +>asyncLoad : Symbol(asyncLoad, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 23, 17)) +>load : Symbol(load, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 17, 1)) + + children: result => result.success as any, +>children : Symbol(children, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 24, 20)) +>result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) +>result.success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) +>result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) +>success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) + +}); // should work fine + diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types new file mode 100644 index 0000000000000..a486c5d20828e --- /dev/null +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types @@ -0,0 +1,65 @@ +=== tests/cases/compiler/overloadedConstructorFixesInferencesAppropriately.ts === +interface Box { + v: T; +>v : T +} + +interface ErrorResult { + readonly error: true +>error : true +>true : true +} + +interface AsyncLoaderProps { + readonly asyncLoad: () => Box; +>asyncLoad : () => Box + + readonly children: (result: Exclude) => string; +>children : (result: Exclude) => string +>result : Exclude +} + +class AsyncLoader { +>AsyncLoader : AsyncLoader + + constructor(props: string, context: any); +>props : string +>context : any + + constructor(props: AsyncLoaderProps); +>props : AsyncLoaderProps + + constructor(...args: any[]) {} +>args : any[] +} + +function load(): Box<{ success: true } | ErrorResult> { +>load : () => Box +>success : true +>true : true + + return null as any; +>null as any : any +>null : null +} + +new AsyncLoader({ +>new AsyncLoader({ asyncLoad: load, children: result => result.success as any,}) : AsyncLoader +>AsyncLoader : typeof AsyncLoader +>{ asyncLoad: load, children: result => result.success as any,} : { asyncLoad: () => Box; children: (result: { success: true; }) => any; } + + asyncLoad: load, +>asyncLoad : () => Box +>load : () => Box + + children: result => result.success as any, +>children : (result: { success: true; }) => any +>result => result.success as any : (result: { success: true; }) => any +>result : { success: true; } +>result.success as any : any +>result.success : true +>result : { success: true; } +>success : true + +}); // should work fine + diff --git a/tests/cases/compiler/overloadedConstructorFixesInferencesAppropriately.ts b/tests/cases/compiler/overloadedConstructorFixesInferencesAppropriately.ts new file mode 100644 index 0000000000000..029316d31c67a --- /dev/null +++ b/tests/cases/compiler/overloadedConstructorFixesInferencesAppropriately.ts @@ -0,0 +1,28 @@ +// @strict: true +interface Box { + v: T; +} + +interface ErrorResult { + readonly error: true +} + +interface AsyncLoaderProps { + readonly asyncLoad: () => Box; + readonly children: (result: Exclude) => string; +} + +class AsyncLoader { + constructor(props: string, context: any); + constructor(props: AsyncLoaderProps); + constructor(...args: any[]) {} +} + +function load(): Box<{ success: true } | ErrorResult> { + return null as any; +} + +new AsyncLoader({ + asyncLoad: load, + children: result => result.success as any, +}); // should work fine