Repository navigation
Can't assign type though it is on both branches of conditional type #51488
Description
Activity
Actually it looks like this is fully intentional and documented:
TypeScript no longer allows types to be assignable to [deferred] conditional types that use
infer, or that are distributive. Doing so previously often ended up causing major performance issues. For more information, see the specific change on GitHub.B extends false ? undefined : (string | undefined)is distributive because it operates on a naked type parameterB.The top of #46429 states:
With this PR, a source type
Sis assignable to a target typeA extends B ? C : Dwhen- The conditional type is not distributive, or is distributive but
Ais never referenced inCorD, and Bhas noinferpositions, andSis assignable toC(except ifAnever assignable toBfor any instantiation), andSis assignable toD(except ifAis always assignable toBfor any instantiation).
All four of those conditions appear to be met in the examples.
Ais never referenced inCorDsinceCandDare primitive,B(from that PR) has noinferkeyword (being the primitivefalse), andSis assignable to bothCandD. Thus, it seems like the intention was to have this working even after that PR.- The conditional type is not distributive, or is distributive but
(and for whatever it's worth, I am definitely not in favor of the TS practice of rolling out breaking changes on semver-feature version number bumps.)
(and for whatever it's worth, I am definitely not in favor of the TS practice of rolling out breaking changes on semver-feature version number bumps.)
TS doesn’t follow semver.
TS doesn’t follow semver.
It clearly does not, but it just looks like it does, leading people to be confused.
Documenting the breaking change with a pointer to more information led by a description suggesting the use case at hand should still work, if the intent was for that not to be the case, leads to more confusion!Otherwise, it seems to me that the intent was to have this working even after that PR, and if the execution doesn't match then that's a bug which should be fixed.
MartinJohns commented
on Nov 11, 2022 ContributorMore actionsbut it just looks like it does, leading people to be confused.
Where does it look like that?
- addedDuplicateAn existing issue was already createdAn existing issue was already created
on Nov 11, 2022 Where does it look like that?
The TS version number of three dot-separated numeric components, in a context surrounded by dependencies and repositories that do (at least claim to) use semver, combined with the overlap in the reasons why you would use semver/TypeScript, lead folks who have not invested tons of time reading the obscure parts of TS documentation to think that TypeScript likely uses semver. It is an incorrect conclusion, but a common one, and leads to folks unintentionally making breaking-change upgrades more often than they otherwise would.
Which Issue is this one tagged as a duplicate of? Tagging it as a duplicate of an already-closed-as-fixed issue, where the fix was undone by a subsequent PR that stated an intention to have something like this still work, would be a pretty disappointing outcome of ensuring it's never fixed.
typescript-bot commented
on Nov 14, 2022 ContributorMore actionsThis issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
It's still not clear what this is a duplicate of.
RyanCavanaugh commented
on Nov 18, 2022 MemberMore actionsWhich Issue is this one tagged as a duplicate of? Tagging it as a duplicate of an already-closed-as-fixed issue, where the fix was undone by a subsequent PR that stated an intention to have something like this still work, would be a pretty disappointing outcome of ensuring it's never fixed.
What are we supposed to do with issues that don't seem to be fixable? Leaving them open forever means that the open issue count grows without bound, commingling impossible work with approachable work and confusing the status of what is available to be done. The process is here to manage our workload and track things that need doing, not to be an ever-growing list of sources of incompleteness in the type system, of which there will always be an infinite number of.
The issue was fixed before and I think it can be fixed again, and the regression does not appear to be intentional based on the description in the PR which leads one to believe this case should still work after that PR. I'd categorize this as a fixable regression bug introduced by the second PR and put it on the backlog for a change that can lead to it working again.
- locked as resolved and limited conversation to collaborators
on Oct 22, 2025
Bug Report
🔎 Search Terms
both sides conditional type assignable
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Errors as noted, plus one on the conditional assignment in the first example.
🙂 Expected behavior
If a variable has a conditional type but type
Tis on both sides of the conditional, I should be able to assign typeTto that variable regardless of which branch of the conditional applies.Cross-links
#30639 is an older PR which claims to fix an issue that sounds a lot like this, and that was merged 3/11/21 - it looks like that was for 4.3 which changed things for the better. Restoring that fix might be a step in the right direction. (There is still an error in the conditional assignment, where the conditional type should be narrowable to allow that assignment, but that might be separable as a different issue.)
#46429 is another PR merged over a year ago, just ahead of version 4.5. The issue reappeared somewhere in the 4.5 range, so it's possible that this PR was the cause of the regression. The issue still exists in the latest version.
In some cases, where the types on each side of the conditional are complex constructed types, it might be harder to figure out if
Tis in fact assignable to both sides of the conditional. However, these examples use primitives, so that's clearly not the source of the issue.