-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Fix inference from enum object type to generic mapped type #30944
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
Changes from all commits
cc2ea68
83f3d2e
436f606
efa16ac
3435451
50fdecc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14960,12 +14960,11 @@ namespace ts { | |
} | ||
// If no inferences can be made to K's constraint, infer from a union of the property types | ||
// in the source to the template type X. | ||
const valueTypes = compact([ | ||
getIndexTypeOfType(source, IndexKind.String), | ||
getIndexTypeOfType(source, IndexKind.Number), | ||
...map(getPropertiesOfType(source), getTypeOfSymbol) | ||
]); | ||
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target)); | ||
const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); | ||
const stringIndexType = getIndexTypeOfType(source, IndexKind.String); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't including the index signature type in the union with the named property types, whereas it was before. Doesn't seem intentional and is potentially an undesirably break, since now properties will be ignored for inference when an index signature exists. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It matches what we do for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, but that's not how we operate with homorphic constraints in play, and that erasure of information is typically undesirable during inference. Take when we infer to IMO, rather than producing a union we should probably be inferring from each value (indexes and properties alike) we find to the target template, rather than producing a union to infer with (and adjusting the inference priority for these inferences to allow a union result to handle the intersection-with-incompatable-index case). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But here we specifically know we're inferring to a non-homomorphic mapped type. And, we're in the final part where we're inferring to the template type, not specific properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but the Especially if you consider |
||
const numberIndexInfo = getNonEnumNumberIndexInfo(source); | ||
const numberIndexType = numberIndexInfo && numberIndexInfo.type; | ||
inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target)); | ||
return true; | ||
} | ||
return false; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object; | ||
declare const a: { [index: string]: number }; | ||
fn(a); | ||
|
||
// Repro from #30218 | ||
|
||
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[]; | ||
|
||
enum E { A = 'foo', B = 'bar' } | ||
|
||
let x: E[] = enumValues(E); |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than all this stuff, we shouldn't we just filter the
enumNumberIndexInfo
singleton from the result ofgetIndexTypeOfType(source, IndexKind.Number)
so intersection-based inferences still work out?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that works.