Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change in behavior around keyof any inference #29765

Closed
mike-north opened this issue Feb 6, 2019 · 1 comment
Closed

Change in behavior around keyof any inference #29765

mike-north opened this issue Feb 6, 2019 · 1 comment
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@mike-north
Copy link

mike-north commented Feb 6, 2019

TypeScript Version: 3.4.0-dev.20190202

Search Terms: any, array, argument

Code

function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
    return {} as any;
}

const myAny: any = {};


// TS 3.2.2 - getProps returns Pick<any, "foo" | "bar">
// TS 3.4   - getProps returns Pick<any, "foo" | "bar">
const o1 = getProps(myAny, ['foo', 'bar']);

// TS 3.2.2 - getProps returns Pick<any, "foo" | "bar">
// TS 3.4   - getProps returns Pick<any, string>
   // └ 🚨 Type 'Pick<any, string>' is missing the following properties
   //   from type '{ foo: any; bar: any; }': foo, bar [2739]
const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']);

Expected behavior:

I expect o2 above to type-check successfully in 3.4

Actual behavior:

Playground Link: NOTE: does not demonstrate the reported behavior, since it's only reproducible in recent 3.4 nightly builds

https://www.typescriptlang.org/play/index.html#src=function%20getProps%3CT%2C%20K%20extends%20keyof%20T%3E(obj%3A%20T%2C%20list%3A%20K%5B%5D)%3A%20Pick%3CT%2C%20K%3E%20%7B%0D%0A%20%20%20%20return%20%7B%7D%20as%20any%3B%0D%0A%7D%0D%0A%0D%0Aconst%20myAny%3A%20any%20%3D%20%7B%7D%3B%0D%0A%0D%0A%2F%2F%20TS%203.2.2%20-%20getProps%20returns%20Pick%3Cany%2C%20%22foo%22%20%7C%20%22bar%22%3E%0D%0A%2F%2F%20TS%203.4%20%20%20-%20getProps%20returns%20Pick%3Cany%2C%20string%3E%0D%0Aconst%20o2%3A%20%7B%20foo%3A%20any%3B%20bar%3A%20any%20%7D%20%3D%20getProps(myAny%2C%20%5B'foo'%2C%20'bar'%5D)%3B%0D%0A%0D%0A%2F%2F%20TS%203.2.2%20-%20getProps%20returns%20Pick%3Cany%2C%20%22foo%22%20%7C%20%22bar%22%3E%0D%0A%2F%2F%20TS%203.4%20%20%20-%20getProps%20returns%20Pick%3Cany%2C%20%22foo%22%20%7C%20%22bar%22%3E%0D%0Aconst%20o3%20%3D%20getProps(myAny%2C%20%5B'foo'%2C%20'bar'%5D)%3B%0D%0A

Related Issues: #29698 #25759

@ahejlsberg
Copy link
Member

Looks like this is an effect of #29478. Previously we'd make no inferences from the return type in the second example, but now we infer from { foo: any; bar: any } to Pick<T, K>. This produces an inference for K, but not for T because Pick<T, K> isn't a homomorphic mapped type (it's partially homomorphic in that it only maps a subset of the properties). Because we have no candidates for T, we end up with an inference of {} from the return type, which then causes us to reduce our inference for K to never. We then proceed with this rather useless contextual type which ends up making matters worse rather than better.

Looks like we need to do better when inferring to Pick<T, K>. I will see what we can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

2 participants