Skip to content

UnwrapPartial: Add test case for non-Partial instantiation#1412

Open
porada wants to merge 3 commits into
sindresorhus:mainfrom
porada:fix/unwrap-partial
Open

UnwrapPartial: Add test case for non-Partial instantiation#1412
porada wants to merge 3 commits into
sindresorhus:mainfrom
porada:fix/unwrap-partial

Conversation

@porada

@porada porada commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

@porada porada force-pushed the fix/unwrap-partial branch from fbb130e to 827be34 Compare April 27, 2026 15:24
@porada porada mentioned this pull request Apr 27, 2026
@sindresorhus

Copy link
Copy Markdown
Owner

I think this change is wrong because the removed guard is what preserves the documented no-op behavior for non-Partial<T> inputs. Without it, a normal object type with both required and optional properties is inferred through Partial<infer ObjectType> and the optional property becomes required.

Please add this regression test:

type MixedRequiredAndOptional = {
	required: string;
	optional?: number;
};

expectType<MixedRequiredAndOptional>({} as UnwrapPartial<MixedRequiredAndOptional>);

This fails with the simplified implementation, but passes with the previous guarded version.

@porada porada changed the title Simplify UnwrapPartial Include an additional guard for UnwrapPartial Apr 27, 2026
@porada

porada commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

Whoa, good catch. Thanks for staying vigilant.

I think this is worth merging for the guard alone.

@som-sm

som-sm commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

This fails with the simplified implementation, but passes with the previous guarded version.

Yeah, the check is necessary in UnwrapPartial, but looks like it's not necessary in UnwrapRequired. Because in UnwrapRequired, non-Required objects won't match the outer conditional, so the result would come directly from the else branch, refer:

type UnwrapRequired<RequiredObjectType> =
	RequiredObjectType extends Required<infer ObjectType>
		? ObjectType
		: 'No Match';

type T1 = UnwrapRequired<{a?: number; b: string}>;
//=> 'No Match'

type T2 = UnwrapRequired<{a: number; b?: string}>;
//=> 'No Match'

type T3 = UnwrapRequired<{a?: number; b?: string}>;
//=> 'No Match'

@som-sm som-sm changed the title Include an additional guard for UnwrapPartial UnwrapPartial: Add test case for non-Partial instantiation Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants