Skip to content

Possible regression in 3.4 with distributive conditional types #30569

@dragomirtitian

Description

@dragomirtitian

TypeScript Version: 3.4.0-dev.201xxxxx

Search Terms:

Code

type UnionKeys<T> = T extends any ? keyof T : never;
type BugHelper<T, TAll> = T extends any ? Exclude<UnionKeys<TAll>, keyof T> : never
type Bug<TAll> =  BugHelper<TAll, TAll>
type R = Bug<{ a : any } | { b: any }> // "a" | "b" in 3.3, never in 3.4

Expected behavior:
R should be "a" | "b" (as it previously was in 3.3)

Actual behavior:
R is never in 3.4

Playground Link: link

Related Issues: Probably cause by #29437, #30489

The code above is a simplification of the StrictUnion type I posted on SO, and this issue was reported there as a comment. The type was also included by another SO user in SimplyTyped

Workaround
For the StrictUnion type a simple workaround is to pass in union keys to StrictUnionHelper. This will achieve the same result as in 3.4:

type StrictUnionHelper<T, TAllKeys extends PropertyKey> = T extends any ? T & Partial<Record<Exclude<TAllKeys, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, UnionKeys<T>>

If breaking change is intended, I would like some guidance on whether the workaround version is likely to remain stable in the next releases or if there is a fundamental issue with the idea behind the type.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions