-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Literal inference causes unexpected errors on a values that trivially satisfy compound type intersections containing any #59473
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
Comments
Which one are you asking us to change? |
It seems like the crux of the problem here is the way literal inference works, I wish it would infer a type of type Constraint = { ml: any } & { ml: 'edge' }
type Resolved = { [K in keyof Constraint]: Constraint[K] } // { ml: any }
const Inferred = { ml: 'edge' } satisfies Resolved // { ml: string }
const Checked: Constraint = Inferred // Type '{ ml: string; }' is not assignable to type '{ ml: "edge"; }' What if instead, literal inference was done against both sides of the intersection, and then the results were intersected? type Constraint = { ml: any } & { ml: 'edge' }
const InferredLeft = { ml: 'edge' } satisfies { ml: any } // { ml: string }
const InferredRight = { ml: 'edge' } satisfies { ml: 'edge' } // { ml: 'edge' }
const Inferred: typeof InferredLeft & typeof InferredRight = { ml: 'edge' }
const Checked: Constraint = Inferred // no error! Maybe this approach would cause other problems though, I haven't thought of one yet. Or maybe another option would be, if the initial literal inference type doesn't satisfy the constraint, the compiler tries the unwidened type (just In most cases literal inference behaves in harmony with how type checking works, but in this case it feels pretty dissonant: const x: { ml: any } & { ml: 'edge' } = { ml: 'edge' } // Type '{ ml: string; }' is not assignable to type '{ ml: any; } & { ml: "edge"; }' It seems not ideal for a RHS that satisfies the LHS type as trivially as this to be an error. |
Also I wish that literal inference wouldn't behave so differently for primitive and compound types: const a = 1 satisfies any & 1 // type of a: 1
const b = [1] satisfies [any & 1] // type of b: [number]
const c = { c: 1 } satisfies { c: any & 1 } // type of c: { c: number }
// would have expected either `number/[number]/{ c: number }` or `1/[1]/{ c: 1 }` |
Btw I don't mean to be pedantic here; the practical downside I experienced from the current behavior is, another dev on my team was so confused by the error message they gave up and used |
I recently introduced changes to #52095 that fix this issue |
@Andarist from reading the description that sounds different to me, since there are no indexed types or mapped types in my minimal repro here, but maybe your PR has additional effects? And am I correct in my assumption that this issue stems from current literal inference behavior? I think all of the following would have to work for this issue to be considered fixed (I would reopen if not): const a: [any] & [1] = [1]
const b: any[] & 1[] = [1, 1]
const c: {a: any} & {a: 1} = {a: 1} |
The issue here is our treatment of That said, we can change the behavior of I'll put up a PR that implements this. |
@ahejlsberg could you take a look at my PR? it already has this logic: https://github.com/microsoft/TypeScript/pull/52095/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8R31639-R31643 |
Makes sense, thank y'all! |
π Search Terms
object intersection literal inference any
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?ts=5.5.4#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wChSB6CuGAC2AGc41ckntc4UA7OCAGwAmcAG5IoDYBF4RMcALIBVAJKkYATzBI4AIQgAPAAo4wTALxwA3qThwQ-APwAuLt3VwqcZXEHBB3fHgiFH5gAC9tOkYaTW0AdxQmHnVSAF9yTwAVeiZBCDYA+AYAVzQ0NgZMYv5+dwgxKCg-SNptMBNxDRitV2FvNB44TGB9OGAYADpKah1i+DptcRwoOwqUAHMW6IHihiRhBKYWbirJbnXeuG4kfaZQdvqkECRuGDVYhXVjCFM4Cz0jCYmAAyKw2OyOFz4fabfBwAA+V2KIAARuI0uRjgx4PJ1ABhXBgP5wAAUD1MLlx31MAEo-gA+JE1cgaHqZYlUoEAbXw9nwAF0PNRkpjpNi4KMLAAeXEE8AQswAIhhSEVHkZWViTFkcHJnXcvP4cJQRDG3BY4BQMGAKP4SCmtk1PXw2Ka5zh0W4EHgiUk624KFtkQg3W0+G4yLRK0RysEmzViOK3EESGG10E+AmJIATABmbPZmkZagAdXoaFoYzuMActmUTAABvYXMkG3wVtFxnAGxHUeIEXBY-GB0mU2n9g2HEA
π» Code
EDIT: simplified examples:
Original example:
π Actual behavior
π Expected behavior
No error and no difference in the reported type for the
ml
property in JSX andMyProps['ml']
Additional information about the issue
I hope that literal inference can be improved to handle this case without an error:
Two potential solutions I proposed below are:
The text was updated successfully, but these errors were encountered: