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
exporttypeU=|{type: 'A';value: null}|{type: 'B';value: string};functioncall<T>(f: ()=>T): T{returnf()}exportfunctionfunctionCall(): U{// should error but does notreturncall(()=>{if(Math.random()){// not assignable to U (missing `value: null`)return{type: 'A'};}return{type: 'B',value: 'test'};});}exportfunctiondirectReturn(): U{if(Math.random()){// Type '{ type: "A"; }' is not assignable to type 'U'.// Property 'value' is missing in type '{ type: "A"; }' but required in type '{ type: "A"; value: null; }'.return{type: 'A'};}return{type: 'B',value: 'test'};}
🙁 Actual behavior
type error in directReturn, but no type error in functionCall
🙂 Expected behavior
type error in both directReturn and functionCall, because {type: 'A'} is not assignable to {type: 'A', value: null}
Additional information about the issue
It does work with exactOptionalPropertyTypes disabled: Playground
With exactOptionalPropertyTypes enabled, the return type of call() is inferred as:
But this doesn't fully explain it, because even assigning the result of call() to a variable before returning it causes the expected error:
exportfunctionfunctionCall(): U{constresult=call(()=>{if(Math.random()){// not assignable to U (missing `value: null`)return{type: 'A'};}return{type: 'B',value: 'test'};});// error as expectedreturnresult;}
The text was updated successfully, but these errors were encountered:
value doesn't need to be falsey. You can do { type: "A"; value: 123 | 456 } | { type: "B"; value: string } as well. it appears to be any literals in fact.
You can also get rid of some of the extra fluff. All in all you can reduce it to this:
If I had to guess there's some specialized check that missed this edge case. It seems quite precisely targeted when the payload is also discriminated. For example:
Perhaps there's some incorrect "fusion" where { type: "A"; value: 123 } | { type: "B"; value: string } is being treated like { type: "A" | "B"; value: never | 123 } = { type: "A" | "B"; value: 123 }?
loganzartman
changed the title
With exactOptionalPropertyTypes enabled, returning an object with missing falsy properties is incorrectly allowed
With exactOptionalPropertyTypes enabled, assigning an object with missing properties is incorrectly allowed
May 9, 2025
loganzartman
changed the title
With exactOptionalPropertyTypes enabled, assigning an object with missing properties is incorrectly allowed
With exactOptionalPropertyTypes enabled, assigning a union with missing literal properties is incorrectly allowed
May 9, 2025
Uh oh!
There was an error while loading. Please reload this page.
🔎 Search Terms
"exactoptionalpropertytypes union", "function call union assignability", "discriminated union assignment allowed incorrectly", "discriminated union assignable missing property"
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play/?exactOptionalPropertyTypes=true&ts=5.9.0-dev.20250508#code/KYDwDg9gTgLgBDAnmYcCqcC8cCQBYAKBwB84BvJFALjgHIBBWgbjgDcBDAGwFdgaA7bp04BfQiXKU+dAELM2XXjQDOMKAEt+AcxFNChAGbd+AYxjqI-OCa6cAPABUAfAAoDNFwEosTuA880DuRQwDDcUFYGXmIEhKCQsHBGpuaWScZmFvwAwrZeNBhk4gD0xXDKABYQQgAmcMBQUNBwAEbc8DUQwMpw-BAw4iFhEdZ5Xj7k4jjqBnAuALLsMBUAdFDs-J0Atl7eRUQ4OKW9-XDsysrqWvzsLZyoMBDoc1vqF5pacAAGHDzSgsIvp4pjghuErBRkNIGLRdFMYlMwSNIdRZLQADQKP40WgwbowWF6IgiTxEhEEeLQeDJTJpGrqEJmABKoXB+We+2mswWS1W602EB2nj2U2ODihdDICChNAARPRZSwRLQ4G8TvBzpdrrd7ggnlI6GhaCtCHBcEcymaAApNFCwRB0X68FVq17vbSqqwG2hSqRyhVKlVteAhACO3AZwDqmmlKElsek8sVWKUvSEnEDJoOSIhfrojDhxP0RBzkhlaMxTuheNUhMIMSAA
💻 Code
🙁 Actual behavior
type error in
directReturn
, but no type error infunctionCall
🙂 Expected behavior
type error in both
directReturn
andfunctionCall
, because{type: 'A'}
is not assignable to{type: 'A', value: null}
Additional information about the issue
It does work with
exactOptionalPropertyTypes
disabled: PlaygroundWith
exactOptionalPropertyTypes
enabled, the return type ofcall()
is inferred as:whereas with it disabled, it's inferred as:
But this doesn't fully explain it, because even assigning the result of
call()
to a variable before returning it causes the expected error:The text was updated successfully, but these errors were encountered: