TypeScript Version: v3.5.1
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.
Playground Link:link
Related Issues:#18538, #19927
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
Expandtype has no effect on assignability.Actual behavior: Line 21 does not compile, stating
Using the
Expandhelper type workaround fixes the assignability problem.Playground Link:link
Related Issues:#18538, #19927