You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
interfaceSharp{// Removing 'Triangle' here to get rid of the union makes it work.type: 'Square'|'Triangle';corners: number;}interfaceRound{type: 'Circle'|'Oval';radius: number;}functiongetCorners(shapes: Sharp[]|Round[]){// Expected `Sharp | undefined` but got `Sharp | Round | undefined`constfoundSharp=shapes.find((shape)=>shape.type==='Square');// Property 'corners' does not exist on type 'Sharp | Round'.// Property 'corners' does not exist on type 'Round'. (2339)returnfoundSharp?.corners;}
🙁 Actual behavior
foundSharp is Sharp | Round | undefined even though it can never be Round due to type.
🙂 Expected behavior
foundSharp should be Sharp | undefined since only sharp shapes can have the type 'Square'.
Additional information about the issue
Setting type in the Sharp interface to only 'Square' makes it work as expected.
The text was updated successfully, but these errors were encountered:
This isn't a TS bug. Your callback isn't inferred as returning a type predicate as implemented in #57465, because it would need to be a one-sided type predicate, which TypeScript doesn't have. The check shape.type === 'Square' can narrow Round | Sharp to Sharp but since shape.type !== 'Square' does not narrow Round | Sharp to Round, no type predicate can be inferred. (See flakyIsString in the text of #57465) If TS had one-sided type predicates as requested in #15048, then the return type could be inferred as something like shape is Shape else false and it would work. When you're using find() you don't care about the false side of the type guard function, but TS does, and there's currently no way to tell it not to.
If you want, you can annotate your callback with a type predicate return type, and while shape is Sharp will work, it's a bit of a lie. Something which works and is true is:
functiongetCorners(shapes: Sharp[]|Round[]){constfoundSharp=shapes.find((shape): shape is typeofshape&{type: "Square"}=>shape.type==='Square');returnfoundSharp?.corners;}
🔎 Search Terms
"discriminated union", "refine union", "array find union property"
🕗 Version & Regression Information
Tried every TypeScript version from 5.2.2 in the playground with the same result.
I found some similar issues that eventually led me to #42384, but I wasn't sure if the root cause is the same?
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.8.0-dev.20241217#code/JYOwLgpgTgZghgYwgAgMoAs5QA7IN4BQAkAPQnIBKEAtgPYBuoA5sgOQAqUwcITANhFbJ00FGFrImEMMi4ATZLRjIwI5AFcQwWiGTU4AawgBnZMBkB3WlAMA6YmACe2CAC42qAI7qsg5AB82Tm5eAVYAbmIEaxBoY3cQdWoAI2hIgF8CUEhYRBQKWk0FQiInF3dWAGFgKAQwgLYAeXo4PgjiKDg5YHV45ESUtIJMghhNBDBtXSkwSpi4gApjTBc+jCxsAG0AXQaCop2ASnxiMmQAUQAPFwmIBQADdZwGoogYUDv75GT1GSZaGSPTDPQL7EAKQKvd6xOT3KI6YwyGCFcFPXAAXmQyzgq1s0LkCyWKwgx3RAD4scTbGUUOi6R5vL5WIdIqRyAAFKC0FxQJxsaJQWJQYxCOS0Ez9AHICCXYCIxS6GkeYG4UEouSsexs5A6znc6B81gCoUi5BiiUgKUyuUyHQqZwoVhgjW2ZALABMAGZPQBOQ4daTqQXIZFFNEAflsxriGSAA
💻 Code
🙁 Actual behavior
foundSharp
isSharp | Round | undefined
even though it can never beRound
due totype
.🙂 Expected behavior
foundSharp
should beSharp | undefined
since only sharp shapes can have the type 'Square'.Additional information about the issue
Setting
type
in the Sharp interface to only 'Square' makes it work as expected.The text was updated successfully, but these errors were encountered: