Skip to content

Commit 8d7da19

Browse files
AgentEnderclaude
andcommitted
fix(parser): improve WithAdditionalProperties type to use intersection
- Change from union type to intersection for better explicit property access - Explicit properties now keep their exact types via intersection - Bracket notation returns union of all possible types (as expected) - Simplify MakeUndefinedPropertiesOptional using mapped type key remapping - Add improved documentation explaining the behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d8f29b8 commit 8d7da19

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

packages/parser/src/lib/option-types/type-resolution.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,21 @@ type BaseLevelAdditionalProperties<TAdditional> =
139139

140140
/**
141141
* Combines explicit properties with an index signature for additional properties.
142+
*
142143
* The index signature value is a union of all possible values (explicit + additional)
143144
* to satisfy TypeScript's constraint that index signatures must be compatible with
144145
* all explicit properties.
146+
*
147+
* This allows:
148+
* - Explicit properties to keep their exact types via the intersection
149+
* - Additional string keys to be added with the additionalProperties type
150+
* - Bracket notation access returns the union of all possible types
145151
*/
146152
export type WithAdditionalProperties<TProperties, TAdditionalProperties> =
147-
| {
148-
[key in keyof TProperties]: TProperties[key];
149-
}
150-
| {
151-
[key: string]: BaseLevelAdditionalProperties<TAdditionalProperties>;
152-
};
153+
TProperties & {
154+
[key: string]: // | TProperties[keyof TProperties]
155+
BaseLevelAdditionalProperties<TAdditionalProperties> | undefined;
156+
};
153157
/**
154158
* Compute the full value type for an object option.
155159
* Uses WithAdditionalProperties when additionalProperties is specified,
@@ -165,15 +169,15 @@ export type ObjectValueType<TProperties, TAdditionalProperties> =
165169
TAdditionalProperties
166170
>;
167171

168-
type PickUndefinedKeys<T> = {
169-
[K in keyof T]: undefined extends T[K] ? K : never;
170-
}[keyof T];
171-
172-
type PickRequiredKeys<T> = {
173-
[K in keyof T]: undefined extends T[K] ? never : K;
174-
}[keyof T];
175-
176-
export type MakeUndefinedPropertiesOptional<T> = Partial<
177-
Pick<T, PickUndefinedKeys<T>>
178-
> &
179-
Pick<T, PickRequiredKeys<T>>;
172+
/**
173+
* Makes properties whose type includes `undefined` optional.
174+
* This allows omitting properties like `{ foo?: string | undefined }` from object literals
175+
* instead of requiring `{ foo: undefined }`.
176+
*
177+
* Uses a simpler mapped type approach that works better with generic keys in .d.ts generation.
178+
*/
179+
export type MakeUndefinedPropertiesOptional<T> = {
180+
[K in keyof T as undefined extends T[K] ? K : never]?: T[K];
181+
} & {
182+
[K in keyof T as undefined extends T[K] ? never : K]: T[K];
183+
};

0 commit comments

Comments
 (0)