Limit type argument inference from binding patterns (#49086)

* WIP

* Don’t widen literals based on bogus contextual type instantiation

* Split tests

* Skip unnecessary inference pass

* Accept test baselines

* Fix stray edit

* Fix type mapper combination

* Revert src/ of 7dc1952a82

* Make empty binding pattern provide no contextual type

* Add missed baseline
This commit is contained in:
Andrew Branch
2022-05-24 09:05:34 -07:00
committed by GitHub
parent 194a2aea0d
commit a2b785b6cb
29 changed files with 604 additions and 97 deletions

View File

@@ -0,0 +1,27 @@
// @strictNullChecks: true
declare function f<T>(): T;
const {} = f(); // error (only in strictNullChecks)
const { p1 } = f(); // error
const [] = f(); // error
const [e1, e2] = f(); // error
// Repro from #43605
type Dispatch<A = { type: any; [extraProps: string]: any }> = { <T extends A>(action: T): T };
type IFuncs = { readonly [key: string]: (...p: any) => void };
type IDestructuring<T extends IFuncs> = { readonly [key in keyof T]?: (...p: Parameters<T[key]>) => void };
type Destructuring<T extends IFuncs, U extends IDestructuring<T>> = (dispatch: Dispatch<any>, 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<T extends IDestructuring<TFuncs1>>(destructuring: Destructuring<TFuncs1, T>): 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)),
})
);

View File

@@ -0,0 +1,3 @@
declare function pick<O, T extends keyof O>(keys: T[], obj?: O): Pick<O, T>;
const _ = pick(['b'], { a: 'a', b: 'b' }); // T: "b"
const { } = pick(['b'], { a: 'a', b: 'b' }); // T: "b" | "a" ??? (before fix)

View File

@@ -0,0 +1,2 @@
declare function f<T>(cb: () => T): T;
const [e1, e2, e3] = f(() => [1, "hi", true]);

View File

@@ -0,0 +1,2 @@
declare function id<T>(x: T): T;
const { f = (x: string) => x.length } = id({ f: x => x.charAt });

View File

@@ -19,7 +19,7 @@ function f1() {
}
function f2() {
var { } = { x: 5, y: "hello" }; // Error, no x and y in target
var { } = { x: 5, y: "hello" }; // Ok, empty binding pattern means nothing
var { x } = { x: 5, y: "hello" }; // Error, no y in target
var { y } = { x: 5, y: "hello" }; // Error, no x in target
var { x, y } = { x: 5, y: "hello" };