From 28fbc0a1ef7fca8548069ed0207ca28c2680450d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 3 Dec 2025 18:46:59 +0100 Subject: [PATCH] Filter return type inferences by constraint applicability (#58910) --- src/compiler/checker.ts | 16 +- ...nferenceContextualReturnTypeUnion1.symbols | 53 ++++ .../inferenceContextualReturnTypeUnion1.types | 82 ++++++ ...nferenceContextualReturnTypeUnion2.symbols | 97 +++++++ .../inferenceContextualReturnTypeUnion2.types | 74 ++++++ ...nferenceContextualReturnTypeUnion3.symbols | 146 +++++++++++ .../inferenceContextualReturnTypeUnion3.types | 237 ++++++++++++++++++ ...nferenceContextualReturnTypeUnion4.symbols | 37 +++ .../inferenceContextualReturnTypeUnion4.types | 36 +++ .../inferenceContextualReturnTypeUnion1.ts | 19 ++ .../inferenceContextualReturnTypeUnion2.ts | 35 +++ .../inferenceContextualReturnTypeUnion3.ts | 44 ++++ .../inferenceContextualReturnTypeUnion4.ts | 17 ++ 13 files changed, 890 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion1.symbols create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion1.types create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion2.symbols create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion2.types create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion3.symbols create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion3.types create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion4.symbols create mode 100644 tests/baselines/reference/inferenceContextualReturnTypeUnion4.types create mode 100644 tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts create mode 100644 tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts create mode 100644 tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts create mode 100644 tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8e5c03560db..bfa81f69646 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27576,10 +27576,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper); - if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { - // If the fallback type satisfies the constraint, we pick it. Otherwise, we pick the constraint. - inference.inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint; + if (inferredType) { + const constraintWithThis = getTypeWithThisArgument(instantiatedConstraint, inferredType); + if (!context.compareTypes(inferredType, constraintWithThis)) { + // If we have a pure return type inference, we may succeed by removing constituents of the inferred type + // that aren't assignable to the constraint type (pure return type inferences are speculation anyway). + const filteredByConstraint = inference.priority === InferencePriority.ReturnType ? filterType(inferredType, t => !!context.compareTypes(t, constraintWithThis)) : neverType; + inferredType = !(filteredByConstraint.flags & TypeFlags.Never) ? filteredByConstraint : undefined; + } } + if (!inferredType) { + // If the fallback type satisfies the constraint, we pick it. Otherwise, we pick the constraint. + inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint; + } + inference.inferredType = inferredType; } clearActiveMapperCaches(); } diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion1.symbols b/tests/baselines/reference/inferenceContextualReturnTypeUnion1.symbols new file mode 100644 index 00000000000..552f8a7d1f2 --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion1.symbols @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts] //// + +=== inferenceContextualReturnTypeUnion1.ts === +// https://github.com/microsoft/TypeScript/issues/50719 + +declare function useCallback1(fn: T): T; +>useCallback1 : Symbol(useCallback1, Decl(inferenceContextualReturnTypeUnion1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 30)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>fn : Symbol(fn, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 50)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 30)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 30)) + +declare function ex2(callback?: (x: number) => void): void; +>ex2 : Symbol(ex2, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 60)) +>callback : Symbol(callback, Decl(inferenceContextualReturnTypeUnion1.ts, 4, 21)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 4, 33)) + +ex2(useCallback1((x) => {})); +>ex2 : Symbol(ex2, Decl(inferenceContextualReturnTypeUnion1.ts, 2, 60)) +>useCallback1 : Symbol(useCallback1, Decl(inferenceContextualReturnTypeUnion1.ts, 0, 0)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 5, 18)) + +declare function ex3(callback: ((x: number) => void) | 5): void; +>ex3 : Symbol(ex3, Decl(inferenceContextualReturnTypeUnion1.ts, 5, 29)) +>callback : Symbol(callback, Decl(inferenceContextualReturnTypeUnion1.ts, 7, 21)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 7, 33)) + +ex3(useCallback1((x) => {})); +>ex3 : Symbol(ex3, Decl(inferenceContextualReturnTypeUnion1.ts, 5, 29)) +>useCallback1 : Symbol(useCallback1, Decl(inferenceContextualReturnTypeUnion1.ts, 0, 0)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 8, 18)) + +// https://github.com/microsoft/TypeScript/issues/41461 + +declare function useCallback2 any>( +>useCallback2 : Symbol(useCallback2, Decl(inferenceContextualReturnTypeUnion1.ts, 8, 29)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 12, 30)) +>args : Symbol(args, Decl(inferenceContextualReturnTypeUnion1.ts, 12, 41)) + + callback: T, +>callback : Symbol(callback, Decl(inferenceContextualReturnTypeUnion1.ts, 12, 65)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 12, 30)) + +): T; +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion1.ts, 12, 30)) + +const test: ((x: string) => void) | undefined = useCallback2((x) => {}); +>test : Symbol(test, Decl(inferenceContextualReturnTypeUnion1.ts, 15, 5)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 15, 14)) +>useCallback2 : Symbol(useCallback2, Decl(inferenceContextualReturnTypeUnion1.ts, 8, 29)) +>x : Symbol(x, Decl(inferenceContextualReturnTypeUnion1.ts, 15, 62)) + diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion1.types b/tests/baselines/reference/inferenceContextualReturnTypeUnion1.types new file mode 100644 index 00000000000..fd85d187364 --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion1.types @@ -0,0 +1,82 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts] //// + +=== inferenceContextualReturnTypeUnion1.ts === +// https://github.com/microsoft/TypeScript/issues/50719 + +declare function useCallback1(fn: T): T; +>useCallback1 : (fn: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>fn : T +> : ^ + +declare function ex2(callback?: (x: number) => void): void; +>ex2 : (callback?: (x: number) => void) => void +> : ^ ^^^ ^^^^^ +>callback : ((x: number) => void) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ + +ex2(useCallback1((x) => {})); +>ex2(useCallback1((x) => {})) : void +> : ^^^^ +>ex2 : (callback?: (x: number) => void) => void +> : ^ ^^^ ^^^^^ +>useCallback1((x) => {}) : (x: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>useCallback1 : (fn: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>(x) => {} : (x: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ + +declare function ex3(callback: ((x: number) => void) | 5): void; +>ex3 : (callback: ((x: number) => void) | 5) => void +> : ^ ^^ ^^^^^ +>callback : ((x: number) => void) | 5 +> : ^^ ^^ ^^^^^ ^^^^^ +>x : number +> : ^^^^^^ + +ex3(useCallback1((x) => {})); +>ex3(useCallback1((x) => {})) : void +> : ^^^^ +>ex3 : (callback: ((x: number) => void) | 5) => void +> : ^ ^^ ^^^^^ +>useCallback1((x) => {}) : (x: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>useCallback1 : (fn: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>(x) => {} : (x: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ + +// https://github.com/microsoft/TypeScript/issues/41461 + +declare function useCallback2 any>( +>useCallback2 : any>(callback: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>args : any[] +> : ^^^^^ + + callback: T, +>callback : T +> : ^ + +): T; +const test: ((x: string) => void) | undefined = useCallback2((x) => {}); +>test : ((x: string) => void) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>x : string +> : ^^^^^^ +>useCallback2((x) => {}) : (x: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>useCallback2 : any>(callback: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>(x) => {} : (x: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>x : string +> : ^^^^^^ + diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion2.symbols b/tests/baselines/reference/inferenceContextualReturnTypeUnion2.symbols new file mode 100644 index 00000000000..d46672fb092 --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion2.symbols @@ -0,0 +1,97 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts] //// + +=== inferenceContextualReturnTypeUnion2.ts === +type Query = ( +>Query : Symbol(Query, Decl(inferenceContextualReturnTypeUnion2.ts, 0, 0)) + + container: HTMLElement, +>container : Symbol(container, Decl(inferenceContextualReturnTypeUnion2.ts, 0, 14)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + ...args: any[] +>args : Symbol(args, Decl(inferenceContextualReturnTypeUnion2.ts, 1, 25)) + +) => + | Error +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + | HTMLElement +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + | HTMLElement[] +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + | Promise +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + | Promise +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + | null; + +interface Queries { +>Queries : Symbol(Queries, Decl(inferenceContextualReturnTypeUnion2.ts, 9, 9)) + + [T: string]: Query; +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 12, 3)) +>Query : Symbol(Query, Decl(inferenceContextualReturnTypeUnion2.ts, 0, 0)) +} + +type FindByText = ( +>FindByText : Symbol(FindByText, Decl(inferenceContextualReturnTypeUnion2.ts, 13, 1)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 15, 16)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + container: HTMLElement, +>container : Symbol(container, Decl(inferenceContextualReturnTypeUnion2.ts, 15, 56)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + text: string, +>text : Symbol(text, Decl(inferenceContextualReturnTypeUnion2.ts, 16, 25)) + +) => Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 15, 16)) + +declare function findByLabelText( +>findByLabelText : Symbol(findByLabelText, Decl(inferenceContextualReturnTypeUnion2.ts, 18, 16)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 20, 33)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + ...args: Parameters> +>args : Symbol(args, Decl(inferenceContextualReturnTypeUnion2.ts, 20, 70)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>FindByText : Symbol(FindByText, Decl(inferenceContextualReturnTypeUnion2.ts, 13, 1)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 20, 33)) + +): ReturnType>; +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>FindByText : Symbol(FindByText, Decl(inferenceContextualReturnTypeUnion2.ts, 13, 1)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion2.ts, 20, 33)) + +const queries = { +>queries : Symbol(queries, Decl(inferenceContextualReturnTypeUnion2.ts, 24, 5)) + + findByLabelText, +>findByLabelText : Symbol(findByLabelText, Decl(inferenceContextualReturnTypeUnion2.ts, 24, 17)) + +}; + +type MapQueries = { +>MapQueries : Symbol(MapQueries, Decl(inferenceContextualReturnTypeUnion2.ts, 26, 2)) +>Q : Symbol(Q, Decl(inferenceContextualReturnTypeUnion2.ts, 28, 16)) +>Queries : Symbol(Queries, Decl(inferenceContextualReturnTypeUnion2.ts, 9, 9)) +>queries : Symbol(queries, Decl(inferenceContextualReturnTypeUnion2.ts, 24, 5)) + + [P in keyof Q]: Q[P]; +>P : Symbol(P, Decl(inferenceContextualReturnTypeUnion2.ts, 29, 3)) +>Q : Symbol(Q, Decl(inferenceContextualReturnTypeUnion2.ts, 28, 16)) +>Q : Symbol(Q, Decl(inferenceContextualReturnTypeUnion2.ts, 28, 16)) +>P : Symbol(P, Decl(inferenceContextualReturnTypeUnion2.ts, 29, 3)) + +}; + diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion2.types b/tests/baselines/reference/inferenceContextualReturnTypeUnion2.types new file mode 100644 index 00000000000..4464c94ddea --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion2.types @@ -0,0 +1,74 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts] //// + +=== inferenceContextualReturnTypeUnion2.ts === +type Query = ( +>Query : Query +> : ^^^^^ + + container: HTMLElement, +>container : HTMLElement +> : ^^^^^^^^^^^ + + ...args: any[] +>args : any[] +> : ^^^^^ + +) => + | Error + | HTMLElement + | HTMLElement[] + | Promise + | Promise + | null; + +interface Queries { + [T: string]: Query; +>T : string +> : ^^^^^^ +} + +type FindByText = ( +>FindByText : FindByText +> : ^^^^^^^^^^^^^ + + container: HTMLElement, +>container : HTMLElement +> : ^^^^^^^^^^^ + + text: string, +>text : string +> : ^^^^^^ + +) => Promise; + +declare function findByLabelText( +>findByLabelText : (container: HTMLElement, text: string) => ReturnType> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...args: Parameters> +>args : [container: HTMLElement, text: string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +): ReturnType>; + +const queries = { +>queries : { findByLabelText: (container: HTMLElement, text: string) => ReturnType>; } +> : ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>{ findByLabelText,} : { findByLabelText: (container: HTMLElement, text: string) => ReturnType>; } +> : ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ + + findByLabelText, +>findByLabelText : (container: HTMLElement, text: string) => ReturnType> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}; + +type MapQueries = { +>MapQueries : MapQueries +> : ^^^^^^^^^^^^^ +>queries : { findByLabelText: (container: HTMLElement, text: string) => ReturnType>; } +> : ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ + + [P in keyof Q]: Q[P]; +}; + diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion3.symbols b/tests/baselines/reference/inferenceContextualReturnTypeUnion3.symbols new file mode 100644 index 00000000000..43c94f2219b --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion3.symbols @@ -0,0 +1,146 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts] //// + +=== inferenceContextualReturnTypeUnion3.ts === +declare function deprecate( +>deprecate : Symbol(deprecate, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 27)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.decorators.d.ts, --, --)) + + fn: T, +>fn : Symbol(fn, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 47)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 27)) + + msg: string, +>msg : Symbol(msg, Decl(inferenceContextualReturnTypeUnion3.ts, 1, 8)) + + code?: string, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 2, 14)) + +): T; +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 27)) + +const soonFrozenObjectDeprecation = ( +>soonFrozenObjectDeprecation : Symbol(soonFrozenObjectDeprecation, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 5)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 37)) + + obj: T, +>obj : Symbol(obj, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 55)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 37)) + + name: string, +>name : Symbol(name, Decl(inferenceContextualReturnTypeUnion3.ts, 7, 9)) + + code: string, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 8, 15)) + + note = "", +>note : Symbol(note, Decl(inferenceContextualReturnTypeUnion3.ts, 9, 15)) + +): T => { +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 37)) + + const message = `${name} will be frozen in future, all modifications are deprecated.${ +>message : Symbol(message, Decl(inferenceContextualReturnTypeUnion3.ts, 12, 7)) +>name : Symbol(name, Decl(inferenceContextualReturnTypeUnion3.ts, 7, 9)) + + note && `\n${note}` +>note : Symbol(note, Decl(inferenceContextualReturnTypeUnion3.ts, 9, 15)) +>note : Symbol(note, Decl(inferenceContextualReturnTypeUnion3.ts, 9, 15)) + + }`; + return new Proxy(obj, { +>Proxy : Symbol(Proxy, Decl(lib.es2015.proxy.d.ts, --, --)) +>obj : Symbol(obj, Decl(inferenceContextualReturnTypeUnion3.ts, 6, 55)) + + set: deprecate( +>set : Symbol(set, Decl(inferenceContextualReturnTypeUnion3.ts, 15, 25)) +>deprecate : Symbol(deprecate, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 0)) + + (target, property, value, receiver) => +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 14)) +>value : Symbol(value, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 24)) +>receiver : Symbol(receiver, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 31)) + + Reflect.set(target, property, value, receiver), +>Reflect.set : Symbol(Reflect.set, Decl(lib.es2015.reflect.d.ts, --, --), Decl(lib.es2015.reflect.d.ts, --, --)) +>Reflect : Symbol(Reflect, Decl(lib.es2015.reflect.d.ts, --, --)) +>set : Symbol(Reflect.set, Decl(lib.es2015.reflect.d.ts, --, --), Decl(lib.es2015.reflect.d.ts, --, --)) +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 14)) +>value : Symbol(value, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 24)) +>receiver : Symbol(receiver, Decl(inferenceContextualReturnTypeUnion3.ts, 17, 31)) + + message, +>message : Symbol(message, Decl(inferenceContextualReturnTypeUnion3.ts, 12, 7)) + + code, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 8, 15)) + + ), + defineProperty: deprecate( +>defineProperty : Symbol(defineProperty, Decl(inferenceContextualReturnTypeUnion3.ts, 21, 6)) +>deprecate : Symbol(deprecate, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 0)) + + (target, property, descriptor) => +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 14)) +>descriptor : Symbol(descriptor, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 24)) + + Reflect.defineProperty(target, property, descriptor), +>Reflect.defineProperty : Symbol(Reflect.defineProperty, Decl(lib.es2015.reflect.d.ts, --, --)) +>Reflect : Symbol(Reflect, Decl(lib.es2015.reflect.d.ts, --, --)) +>defineProperty : Symbol(Reflect.defineProperty, Decl(lib.es2015.reflect.d.ts, --, --)) +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 14)) +>descriptor : Symbol(descriptor, Decl(inferenceContextualReturnTypeUnion3.ts, 23, 24)) + + message, +>message : Symbol(message, Decl(inferenceContextualReturnTypeUnion3.ts, 12, 7)) + + code, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 8, 15)) + + ), + deleteProperty: deprecate( +>deleteProperty : Symbol(deleteProperty, Decl(inferenceContextualReturnTypeUnion3.ts, 27, 6)) +>deprecate : Symbol(deprecate, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 0)) + + (target, property) => Reflect.deleteProperty(target, property), +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 29, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 29, 14)) +>Reflect.deleteProperty : Symbol(Reflect.deleteProperty, Decl(lib.es2015.reflect.d.ts, --, --)) +>Reflect : Symbol(Reflect, Decl(lib.es2015.reflect.d.ts, --, --)) +>deleteProperty : Symbol(Reflect.deleteProperty, Decl(lib.es2015.reflect.d.ts, --, --)) +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 29, 7)) +>property : Symbol(property, Decl(inferenceContextualReturnTypeUnion3.ts, 29, 14)) + + message, +>message : Symbol(message, Decl(inferenceContextualReturnTypeUnion3.ts, 12, 7)) + + code, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 8, 15)) + + ), + setPrototypeOf: deprecate( +>setPrototypeOf : Symbol(setPrototypeOf, Decl(inferenceContextualReturnTypeUnion3.ts, 32, 6)) +>deprecate : Symbol(deprecate, Decl(inferenceContextualReturnTypeUnion3.ts, 0, 0)) + + (target, proto) => Reflect.setPrototypeOf(target, proto), +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 34, 7)) +>proto : Symbol(proto, Decl(inferenceContextualReturnTypeUnion3.ts, 34, 14)) +>Reflect.setPrototypeOf : Symbol(Reflect.setPrototypeOf, Decl(lib.es2015.reflect.d.ts, --, --)) +>Reflect : Symbol(Reflect, Decl(lib.es2015.reflect.d.ts, --, --)) +>setPrototypeOf : Symbol(Reflect.setPrototypeOf, Decl(lib.es2015.reflect.d.ts, --, --)) +>target : Symbol(target, Decl(inferenceContextualReturnTypeUnion3.ts, 34, 7)) +>proto : Symbol(proto, Decl(inferenceContextualReturnTypeUnion3.ts, 34, 14)) + + message, +>message : Symbol(message, Decl(inferenceContextualReturnTypeUnion3.ts, 12, 7)) + + code, +>code : Symbol(code, Decl(inferenceContextualReturnTypeUnion3.ts, 8, 15)) + + ), + }); +}; diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion3.types b/tests/baselines/reference/inferenceContextualReturnTypeUnion3.types new file mode 100644 index 00000000000..538f7397a03 --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion3.types @@ -0,0 +1,237 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts] //// + +=== inferenceContextualReturnTypeUnion3.ts === +declare function deprecate( +>deprecate : (fn: T, msg: string, code?: string) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^ + + fn: T, +>fn : T +> : ^ + + msg: string, +>msg : string +> : ^^^^^^ + + code?: string, +>code : string | undefined +> : ^^^^^^^^^^^^^^^^^^ + +): T; + +const soonFrozenObjectDeprecation = ( +>soonFrozenObjectDeprecation : (obj: T, name: string, code: string, note?: string) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^ +>( obj: T, name: string, code: string, note = "",): T => { const message = `${name} will be frozen in future, all modifications are deprecated.${ note && `\n${note}` }`; return new Proxy(obj, { set: deprecate( (target, property, value, receiver) => Reflect.set(target, property, value, receiver), message, code, ), defineProperty: deprecate( (target, property, descriptor) => Reflect.defineProperty(target, property, descriptor), message, code, ), deleteProperty: deprecate( (target, property) => Reflect.deleteProperty(target, property), message, code, ), setPrototypeOf: deprecate( (target, proto) => Reflect.setPrototypeOf(target, proto), message, code, ), });} : (obj: T, name: string, code: string, note?: string) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^ + + obj: T, +>obj : T +> : ^ + + name: string, +>name : string +> : ^^^^^^ + + code: string, +>code : string +> : ^^^^^^ + + note = "", +>note : string +> : ^^^^^^ +>"" : "" +> : ^^ + +): T => { + const message = `${name} will be frozen in future, all modifications are deprecated.${ +>message : string +> : ^^^^^^ +>`${name} will be frozen in future, all modifications are deprecated.${ note && `\n${note}` }` : string +> : ^^^^^^ +>name : string +> : ^^^^^^ + + note && `\n${note}` +>note && `\n${note}` : string +> : ^^^^^^ +>note : string +> : ^^^^^^ +>`\n${note}` : string +> : ^^^^^^ +>note : string +> : ^^^^^^ + + }`; + return new Proxy(obj, { +>new Proxy(obj, { set: deprecate( (target, property, value, receiver) => Reflect.set(target, property, value, receiver), message, code, ), defineProperty: deprecate( (target, property, descriptor) => Reflect.defineProperty(target, property, descriptor), message, code, ), deleteProperty: deprecate( (target, property) => Reflect.deleteProperty(target, property), message, code, ), setPrototypeOf: deprecate( (target, proto) => Reflect.setPrototypeOf(target, proto), message, code, ), }) : T +> : ^ +>Proxy : ProxyConstructor +> : ^^^^^^^^^^^^^^^^ +>obj : T +> : ^ +>{ set: deprecate( (target, property, value, receiver) => Reflect.set(target, property, value, receiver), message, code, ), defineProperty: deprecate( (target, property, descriptor) => Reflect.defineProperty(target, property, descriptor), message, code, ), deleteProperty: deprecate( (target, property) => Reflect.deleteProperty(target, property), message, code, ), setPrototypeOf: deprecate( (target, proto) => Reflect.setPrototypeOf(target, proto), message, code, ), } : { set: (target: T, property: string | symbol, value: any, receiver: any) => boolean; defineProperty: (target: T, property: string | symbol, descriptor: PropertyDescriptor) => boolean; deleteProperty: (target: T, property: string | symbol) => boolean; setPrototypeOf: (target: T, proto: object | null) => boolean; } +> : ^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + set: deprecate( +>set : (target: T, property: string | symbol, value: any, receiver: any) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^ +>deprecate( (target, property, value, receiver) => Reflect.set(target, property, value, receiver), message, code, ) : (target: T, property: string | symbol, value: any, receiver: any) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^ +>deprecate : (fn: T_1, msg: string, code?: string) => T_1 +> : ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^ + + (target, property, value, receiver) => +>(target, property, value, receiver) => Reflect.set(target, property, value, receiver) : (target: T, property: string | symbol, value: any, receiver: any) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ +>value : any +>receiver : any + + Reflect.set(target, property, value, receiver), +>Reflect.set(target, property, value, receiver) : boolean +> : ^^^^^^^ +>Reflect.set : { (target: T_1, propertyKey: P, value: P extends keyof T_1 ? T_1[P] : any, receiver?: any): boolean; (target: object, propertyKey: PropertyKey, value: any, receiver?: any): boolean; } +> : ^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^ +>Reflect : typeof Reflect +> : ^^^^^^^^^^^^^^ +>set : { (target: T_1, propertyKey: P, value: P extends keyof T_1 ? T_1[P] : any, receiver?: any): boolean; (target: object, propertyKey: PropertyKey, value: any, receiver?: any): boolean; } +> : ^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ +>value : any +>receiver : any + + message, +>message : string +> : ^^^^^^ + + code, +>code : string +> : ^^^^^^ + + ), + defineProperty: deprecate( +>defineProperty : (target: T, property: string | symbol, descriptor: PropertyDescriptor) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate( (target, property, descriptor) => Reflect.defineProperty(target, property, descriptor), message, code, ) : (target: T, property: string | symbol, descriptor: PropertyDescriptor) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate : (fn: T_1, msg: string, code?: string) => T_1 +> : ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^ + + (target, property, descriptor) => +>(target, property, descriptor) => Reflect.defineProperty(target, property, descriptor) : (target: T, property: string | symbol, descriptor: PropertyDescriptor) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ +>descriptor : PropertyDescriptor +> : ^^^^^^^^^^^^^^^^^^ + + Reflect.defineProperty(target, property, descriptor), +>Reflect.defineProperty(target, property, descriptor) : boolean +> : ^^^^^^^ +>Reflect.defineProperty : (target: object, propertyKey: PropertyKey, attributes: PropertyDescriptor & ThisType) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>Reflect : typeof Reflect +> : ^^^^^^^^^^^^^^ +>defineProperty : (target: object, propertyKey: PropertyKey, attributes: PropertyDescriptor & ThisType) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ +>descriptor : PropertyDescriptor +> : ^^^^^^^^^^^^^^^^^^ + + message, +>message : string +> : ^^^^^^ + + code, +>code : string +> : ^^^^^^ + + ), + deleteProperty: deprecate( +>deleteProperty : (target: T, property: string | symbol) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate( (target, property) => Reflect.deleteProperty(target, property), message, code, ) : (target: T, property: string | symbol) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate : (fn: T_1, msg: string, code?: string) => T_1 +> : ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^ + + (target, property) => Reflect.deleteProperty(target, property), +>(target, property) => Reflect.deleteProperty(target, property) : (target: T, property: string | symbol) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ +>Reflect.deleteProperty(target, property) : boolean +> : ^^^^^^^ +>Reflect.deleteProperty : (target: object, propertyKey: PropertyKey) => boolean +> : ^ ^^ ^^ ^^ ^^^^^ +>Reflect : typeof Reflect +> : ^^^^^^^^^^^^^^ +>deleteProperty : (target: object, propertyKey: PropertyKey) => boolean +> : ^ ^^ ^^ ^^ ^^^^^ +>target : T +> : ^ +>property : string | symbol +> : ^^^^^^^^^^^^^^^ + + message, +>message : string +> : ^^^^^^ + + code, +>code : string +> : ^^^^^^ + + ), + setPrototypeOf: deprecate( +>setPrototypeOf : (target: T, proto: object | null) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate( (target, proto) => Reflect.setPrototypeOf(target, proto), message, code, ) : (target: T, proto: object | null) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>deprecate : (fn: T_1, msg: string, code?: string) => T_1 +> : ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^ + + (target, proto) => Reflect.setPrototypeOf(target, proto), +>(target, proto) => Reflect.setPrototypeOf(target, proto) : (target: T, proto: object | null) => boolean +> : ^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>target : T +> : ^ +>proto : object | null +> : ^^^^^^^^^^^^^ +>Reflect.setPrototypeOf(target, proto) : boolean +> : ^^^^^^^ +>Reflect.setPrototypeOf : (target: object, proto: object | null) => boolean +> : ^ ^^ ^^ ^^ ^^^^^ +>Reflect : typeof Reflect +> : ^^^^^^^^^^^^^^ +>setPrototypeOf : (target: object, proto: object | null) => boolean +> : ^ ^^ ^^ ^^ ^^^^^ +>target : T +> : ^ +>proto : object | null +> : ^^^^^^^^^^^^^ + + message, +>message : string +> : ^^^^^^ + + code, +>code : string +> : ^^^^^^ + + ), + }); +}; diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion4.symbols b/tests/baselines/reference/inferenceContextualReturnTypeUnion4.symbols new file mode 100644 index 00000000000..c4d39728acb --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion4.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts] //// + +=== inferenceContextualReturnTypeUnion4.ts === +// https://github.com/microsoft/TypeScript/issues/57905 + +export abstract class Storage { +>Storage : Symbol(Storage, Decl(inferenceContextualReturnTypeUnion4.ts, 0, 0)) + + abstract get(): T | Promise; +>get : Symbol(Storage.get, Decl(inferenceContextualReturnTypeUnion4.ts, 2, 31)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 3, 17)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 3, 17)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 3, 17)) +} + +export abstract class SyncStorage extends Storage { +>SyncStorage : Symbol(SyncStorage, Decl(inferenceContextualReturnTypeUnion4.ts, 4, 1)) +>Storage : Symbol(Storage, Decl(inferenceContextualReturnTypeUnion4.ts, 0, 0)) + + abstract override get(): T; +>get : Symbol(SyncStorage.get, Decl(inferenceContextualReturnTypeUnion4.ts, 6, 51)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 7, 26)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 7, 26)) +} + +export abstract class ASyncStorage extends Storage { +>ASyncStorage : Symbol(ASyncStorage, Decl(inferenceContextualReturnTypeUnion4.ts, 8, 1)) +>Storage : Symbol(Storage, Decl(inferenceContextualReturnTypeUnion4.ts, 0, 0)) + + abstract override get(): Promise; +>get : Symbol(ASyncStorage.get, Decl(inferenceContextualReturnTypeUnion4.ts, 10, 52)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 11, 26)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(inferenceContextualReturnTypeUnion4.ts, 11, 26)) +} + diff --git a/tests/baselines/reference/inferenceContextualReturnTypeUnion4.types b/tests/baselines/reference/inferenceContextualReturnTypeUnion4.types new file mode 100644 index 00000000000..af2d1a21a96 --- /dev/null +++ b/tests/baselines/reference/inferenceContextualReturnTypeUnion4.types @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts] //// + +=== inferenceContextualReturnTypeUnion4.ts === +// https://github.com/microsoft/TypeScript/issues/57905 + +export abstract class Storage { +>Storage : Storage +> : ^^^^^^^ + + abstract get(): T | Promise; +>get : () => T | Promise +> : ^ ^^^^^^^^^ ^^^^^^^ +} + +export abstract class SyncStorage extends Storage { +>SyncStorage : SyncStorage +> : ^^^^^^^^^^^ +>Storage : Storage +> : ^^^^^^^ + + abstract override get(): T; +>get : () => T +> : ^ ^^^^^^^^^ ^^^^^^^ +} + +export abstract class ASyncStorage extends Storage { +>ASyncStorage : ASyncStorage +> : ^^^^^^^^^^^^ +>Storage : Storage +> : ^^^^^^^ + + abstract override get(): Promise; +>get : () => Promise +> : ^ ^^^^^^^^^ ^^^^^^^ +} + diff --git a/tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts b/tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts new file mode 100644 index 00000000000..ab3963fd9d6 --- /dev/null +++ b/tests/cases/compiler/inferenceContextualReturnTypeUnion1.ts @@ -0,0 +1,19 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/50719 + +declare function useCallback1(fn: T): T; + +declare function ex2(callback?: (x: number) => void): void; +ex2(useCallback1((x) => {})); + +declare function ex3(callback: ((x: number) => void) | 5): void; +ex3(useCallback1((x) => {})); + +// https://github.com/microsoft/TypeScript/issues/41461 + +declare function useCallback2 any>( + callback: T, +): T; +const test: ((x: string) => void) | undefined = useCallback2((x) => {}); diff --git a/tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts b/tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts new file mode 100644 index 00000000000..02024913449 --- /dev/null +++ b/tests/cases/compiler/inferenceContextualReturnTypeUnion2.ts @@ -0,0 +1,35 @@ +// @strict: true +// @lib: esnext, dom +// @noEmit: true + +type Query = ( + container: HTMLElement, + ...args: any[] +) => + | Error + | HTMLElement + | HTMLElement[] + | Promise + | Promise + | null; + +interface Queries { + [T: string]: Query; +} + +type FindByText = ( + container: HTMLElement, + text: string, +) => Promise; + +declare function findByLabelText( + ...args: Parameters> +): ReturnType>; + +const queries = { + findByLabelText, +}; + +type MapQueries = { + [P in keyof Q]: Q[P]; +}; diff --git a/tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts b/tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts new file mode 100644 index 00000000000..195900bfc38 --- /dev/null +++ b/tests/cases/compiler/inferenceContextualReturnTypeUnion3.ts @@ -0,0 +1,44 @@ +// @strict: true +// @lib: esnext +// @noEmit: true + +declare function deprecate( + fn: T, + msg: string, + code?: string, +): T; + +const soonFrozenObjectDeprecation = ( + obj: T, + name: string, + code: string, + note = "", +): T => { + const message = `${name} will be frozen in future, all modifications are deprecated.${ + note && `\n${note}` + }`; + return new Proxy(obj, { + set: deprecate( + (target, property, value, receiver) => + Reflect.set(target, property, value, receiver), + message, + code, + ), + defineProperty: deprecate( + (target, property, descriptor) => + Reflect.defineProperty(target, property, descriptor), + message, + code, + ), + deleteProperty: deprecate( + (target, property) => Reflect.deleteProperty(target, property), + message, + code, + ), + setPrototypeOf: deprecate( + (target, proto) => Reflect.setPrototypeOf(target, proto), + message, + code, + ), + }); +}; \ No newline at end of file diff --git a/tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts b/tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts new file mode 100644 index 00000000000..cbc69df35b2 --- /dev/null +++ b/tests/cases/compiler/inferenceContextualReturnTypeUnion4.ts @@ -0,0 +1,17 @@ +// @strict: true +// @lib: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/57905 + +export abstract class Storage { + abstract get(): T | Promise; +} + +export abstract class SyncStorage extends Storage { + abstract override get(): T; +} + +export abstract class ASyncStorage extends Storage { + abstract override get(): Promise; +}