Closed
Description
π Search Terms
object intersection literal inference any
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about intersections and inference
β― Playground Link
π» Code
EDIT: simplified examples:
const a: [any] & [1] = [1] // Type '[number]' is not assignable to type '[1]'
const b: { ml: any } & { ml: 'edge' } = { ml: 'edge' } // Type '{ ml: string; }' is not assignable to type '{ ml: any; } & { ml: "edge"; }'
Original example:
import React from 'react'
// this comes from an old version of MUI
type BoxProps = {
ml?: any // I didn't realize this type was any
}
// This doesn't successfully override the property type and I can fix it.
// But the error message this caused was nonsensical and needs improvement
type MyProps = BoxProps & {
ml?: 'edge' | number
}
const MyComp = (props: MyProps) => null
type T = MyProps['ml'] // any
const x = <MyComp ml="edge" /> // Types of property 'ml' are incompatible.
// Type 'string' is not assignable to type 'number | "edge" | undefined'.(2322)
// Which is it? Is `ml: any` or is it `number | "edge" | undefined`?
π Actual behavior
Type '{ ml: string; }' is not assignable to type '{ ml?: number | "edge" | undefined; }'.
Types of property 'ml' are incompatible.
Type 'string' is not assignable to type 'number | "edge" | undefined'.(2322)
π Expected behavior
No error and no difference in the reported type for the ml
property in JSX and MyProps['ml']
Additional information about the issue
I hope that literal inference can be improved to handle this case without an error:
const x: { ml: any } & { ml: 'edge' } = { ml: 'edge' }
Two potential solutions I proposed below are:
- Run a separate literal inference on each half of the required intersection type, then intersect the inferred types
- Fall back to unwidened type if it satisfies the required type but literal inference doesn't