TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Generic functions combining a conditional type and an intersection are not assignable to themselves

Open ehmicky opened this issue 3 years ago • 1 comments

🔎 Search Terms

"same type assignable" "Two different types with this name exist, but they are unrelated."

🕗 Version & Regression Information

Please keep and fill in the line that best applies:

  • This is a crash
  • This is the behavior in every version I tried (3.3.3 to nightly), and I reviewed the FAQ for entries about it

⏯ Playground Link

Playground link with relevant code

💻 Code

declare let a: <T>() => (T extends true ? true : false) & boolean
declare let b: <T>() => (T extends true ? true : false) & boolean
a = b

🙁 Actual behavior

This produces the following error message:

Type '<T>() => (T extends true ? true : false) & boolean' is not assignable to 
type '<T>() => (T extends true ? true : false) & boolean'. 
Two different types with this name exist, but they are unrelated.
  Type 'false' is not assignable to type '(T extends true ? true : false) & boolean'.

Also, the following unexpectedly removes the error message:

  • Removing & boolean
  • Replacing T extends true ? true : false by true
  • Replacing T extends true ? true : false by T extends true ? true : true
  • Replacing b's type by typeof a

🙂 Expected behavior

Since the two types are identical, a and b should be assignable to each other.

ehmicky avatar Nov 03 '22 19:11 ehmicky

Hmm, yeah, this looks like an issue in type inference between similar intersections.

ahejlsberg avatar Nov 04 '22 14:11 ahejlsberg

Thanks a lot @ahejlsberg for the quick fix! :rocket:

ehmicky avatar Nov 05 '22 13:11 ehmicky

Sorry for a bit unrelated comment (it's too long to search for similar issues and I'm too lazy to create a new one), but similar thing happening here when I try to return 1 and 2. It throws error saying Type '1' is not assignable to type 'Options["enabled"] extends true ? 1 : 2'.ts(2322).

function query<Options extends { enabled?: boolean }>(options?: Options): Options["enabled"] extends true ? 1 : 2 {
  if (options?.enabled) {
    return 1
  }
 
  return 2
}

FrameMuse avatar Jan 12 '23 20:01 FrameMuse

@FrameMuse see #33912

RyanCavanaugh avatar Jan 12 '23 20:01 RyanCavanaugh