From 73e58ea929e3004b9b8e4a9eb0acef6caf2f88bb Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 12 May 2022 10:06:10 -0700 Subject: [PATCH] Split tests --- src/compiler/checker.ts | 12 ++++--- ...ndingPatternCannotBeOnlyInferenceSource.ts | 25 +++++++++++++++ ...tternContextualTypeDoesNotCauseWidening.ts | 3 ++ .../compiler/inferTupleFromBindingPattern.ts | 31 ++----------------- 4 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 tests/cases/compiler/bindingPatternCannotBeOnlyInferenceSource.ts create mode 100644 tests/cases/compiler/bindingPatternContextualTypeDoesNotCauseWidening.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 350bff0aa8a..25fd5004567 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21248,11 +21248,15 @@ namespace ts { type; } - function getWidenedLiteralLikeTypeForContextualType(type: Type, contextualType: Type | undefined, contextNode?: Node) { - if (!isLiteralOfContextualType(type, contextualType) && !(contextNode && isLiteralOfContextualType(type, instantiateContextualType(contextualType, contextNode)))) { - type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type)); + function getWidenedLiteralLikeTypeForContextualType(type: Type, contextualType: Type | undefined, node?: Node) { + if (isLiteralOfContextualType(type, contextualType)) { + return type; } - return type; + const instantiatedContextualType = node && instantiateContextualType(contextualType, node) || contextualType; + if (instantiatedContextualType !== contextualType && isLiteralOfContextualType(type, instantiatedContextualType)) { + return type; + } + return getWidenedUniqueESSymbolType(getWidenedLiteralType(type)); } function getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(type: Type | undefined, contextualSignatureReturnType: Type | undefined, isAsync: boolean) { diff --git a/tests/cases/compiler/bindingPatternCannotBeOnlyInferenceSource.ts b/tests/cases/compiler/bindingPatternCannotBeOnlyInferenceSource.ts new file mode 100644 index 00000000000..0ac5a1f26b8 --- /dev/null +++ b/tests/cases/compiler/bindingPatternCannotBeOnlyInferenceSource.ts @@ -0,0 +1,25 @@ +declare function f(): T; +const {} = f(); // error +const { p1 } = f(); // error +const [] = f(); // error +const [e1, e2] = f(); // error + +// Repro from #43605 +type Dispatch = { (action: T): T }; +type IFuncs = { readonly [key: string]: (...p: any) => void }; +type IDestructuring = { readonly [key in keyof T]?: (...p: Parameters) => void }; +type Destructuring> = (dispatch: Dispatch, funcs: T) => U; +const funcs1 = { + funcA: (a: boolean): void => {}, + funcB: (b: string, bb: string): void => {}, + funcC: (c: number, cc: number, ccc: boolean): void => {}, +}; +type TFuncs1 = typeof funcs1; +declare function useReduxDispatch1>(destructuring: Destructuring): T; +const {} = useReduxDispatch1( + (d, f) => ({ + funcA: (...p) => d(f.funcA(...p)), // p should be inferrable + funcB: (...p) => d(f.funcB(...p)), + funcC: (...p) => d(f.funcC(...p)), + }) +); diff --git a/tests/cases/compiler/bindingPatternContextualTypeDoesNotCauseWidening.ts b/tests/cases/compiler/bindingPatternContextualTypeDoesNotCauseWidening.ts new file mode 100644 index 00000000000..a86b8918ebf --- /dev/null +++ b/tests/cases/compiler/bindingPatternContextualTypeDoesNotCauseWidening.ts @@ -0,0 +1,3 @@ +declare function pick(keys: T[], obj?: O): Pick; +const _ = pick(['b'], { a: 'a', b: 'b' }); // T: "b" +const { } = pick(['b'], { a: 'a', b: 'b' }); // T: "b" | "a" ??? (before fix) diff --git a/tests/cases/compiler/inferTupleFromBindingPattern.ts b/tests/cases/compiler/inferTupleFromBindingPattern.ts index c839d16f8e8..7c0c1dea981 100644 --- a/tests/cases/compiler/inferTupleFromBindingPattern.ts +++ b/tests/cases/compiler/inferTupleFromBindingPattern.ts @@ -1,29 +1,2 @@ -declare function f2(cb: () => T): T; -const [e1, e2, e3] = f2(() => [1, "hi", true]); - -declare function f1(): T; -const {} = f1(); // error -const { p1 } = f1(); // error - -declare function pick(keys: T[], obj?: O): Pick; -const _ = pick(['b'], { a: 'a', b: 'b' }); // T: "b" -const { } = pick(['b'], { a: 'a', b: 'b' }); // T: "b" | "a" ??? - -type Dispatch = { (action: T): T }; -type IFuncs = { readonly [key: string]: (...p: any) => void }; -type IDestructuring = { readonly [key in keyof T]?: (...p: Parameters) => void }; -type Destructuring> = (dispatch: Dispatch, funcs: T) => U; -const funcs1 = { - funcA: (a: boolean): void => {}, - funcB: (b: string, bb: string): void => {}, - funcC: (c: number, cc: number, ccc: boolean): void => {}, -}; -type TFuncs1 = typeof funcs1; -declare function useReduxDispatch1>(destructuring: Destructuring): T; -const {} = useReduxDispatch1( - (d, f) => ({ - funcA: (...p) => d(f.funcA(...p)), - funcB: (...p) => d(f.funcB(...p)), - funcC: (...p) => d(f.funcC(...p)) - }) -); +declare function f(cb: () => T): T; +const [e1, e2, e3] = f(() => [1, "hi", true]);