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
Search Terms: union partial type assignable structure
Code
// Data typesinterfaceKey{type: "key";key: string;}interfaceKeyValue{type: "key-value";key: string;value: string;}typeEither=Key|KeyValue;typeCommon=Pick<Either,"type"|"key">;// Test cases// Structurally-compatible assignmentconsteither: PartialEither=nullasanyasCommon;// Type-guardingif(either.type==="key-value"){either.value;}// Problematic type definitions// Using this intermediate type so I can still rely on 'type' as the discriminant property of// the PartialEither type. The naive// Pick<Either, "type" | "key"> & Partial<Omit<Either, "type" | "key">>// would lose the relationship between `type` and shape, causing the type guard above to fail.type_PartialEither<TextendsEither>=Pick<T,"type"|"key">&Partial<Omit<T,"type"|"key">>;typePartialKey=_PartialEither<Key>;typePartialKeyValue=_PartialEither<KeyValue>;typePartialEither=PartialKey|PartialKeyValue;// This type seems to force the compiler to reinterpret the partial types into a slightly// different representation that's logically equivalent but properly assignable. From:// https://stackoverflow.com/questions/57780109/union-of-partial-types-in-typescript-cant-be-type-narrowedtypeExpand<T>=Textends infer O ? {[KinkeyofO]: O[K]} : never;// Change the definition to this version to see the test cases above work.// type PartialEither = Expand<PartialKey | PartialKeyValue>;
Expected behavior: Line 21, the structurally-compatible assignment, compiles, without a workaround. Using the Expand type has no effect on assignability.
Actual behavior: Line 21 does not compile, stating
Type 'Pick<Either, "key" | "type">' is not assignable to type 'PartialEither'.
Type 'Pick<Either, "key" | "type">' is not assignable to type '_PartialEither<KeyValue>'.
Type 'Pick<Either, "key" | "type">' is not assignable to type 'Pick<KeyValue, "key" | "type">'.
Types of property 'type' are incompatible.
Type '"key" | "key-value"' is not assignable to type '"key-value"'.
Type '"key"' is not assignable to type '"key-value"'.
Using the Expand helper type workaround fixes the assignability problem.
The text was updated successfully, but these errors were encountered:
seansfkelley
changed the title
Union of partial types is not assignable to common sub-type of all union members
Union of partial types: common super type of all union members is not assignable to union type
Sep 4, 2019
The reason why Expand works is probably because of this #30779; both approaches do not work pre 3.5. It seems that PartialEither as defined is not considered a discriminated union in that logic. TypeScript clearly understands that PartialEither is a discriminated union though, evidenced by:
TypeScript Version: v3.5.1
Search Terms: union partial type assignable structure
Code
Expected behavior: Line 21, the structurally-compatible assignment, compiles, without a workaround. Using the
Expand
type has no effect on assignability.Actual behavior: Line 21 does not compile, stating
Using the
Expand
helper type workaround fixes the assignability problem.Playground Link: link
Related Issues: #18538, #19927
The text was updated successfully, but these errors were encountered: