Skip to content

Commit

Permalink
SharedUnionFieldsDeep: Fix support for optional fields (#988)
Browse files Browse the repository at this point in the history
  • Loading branch information
Emiyaaaaa authored Nov 26, 2024
1 parent 196051f commit 4b49b93
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
7 changes: 6 additions & 1 deletion source/shared-union-fields-deep.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,18 @@ export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOp
Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
*/
type SharedObjectUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions> =
// `keyof Union` can extract the same key in union type, if there is no same key, return never.
keyof Union extends infer Keys
? IsNever<Keys> extends false
? {
[Key in keyof Union]:
Union[Key] extends NonRecursiveType
? Union[Key]
: SharedUnionFieldsDeep<Union[Key], Options>
// Remove `undefined` from the union to support optional
// fields, then recover `undefined` if union was already undefined.
: SharedUnionFieldsDeep<Exclude<Union[Key], undefined>, Options> | (
undefined extends Required<Union>[Key] ? undefined : never
)
}
: {}
: Union;
Expand Down
11 changes: 11 additions & 0 deletions test-d/shared-union-fields-deep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,14 @@ expectType<TestingType>(same);
// Test for propagation with non union root object
declare const nonUnionRootType: SharedUnionFieldsDeep<{union: {number: number; boolean: boolean} | {number: number}}>;
expectType<{union: {number: number}}>(nonUnionRootType);

declare const unionWithUndefined: SharedUnionFieldsDeep<{
a?: {a: string; foo: number} | {a: string; bar: string} | undefined;
b?: {a: string; foo: number} | {a: string; bar: string};
c: {a: string; foo: number} | {a: string; bar: string} | undefined;
}>;
expectType<{
a?: {a: string} | undefined;
b?: {a: string};
c: {a: string} | undefined;
}>(unionWithUndefined);

0 comments on commit 4b49b93

Please sign in to comment.