diff --git a/src/types/DeepStrictMerge.ts b/src/types/DeepStrictMerge.ts index 18a576b..8fa07c3 100644 --- a/src/types/DeepStrictMerge.ts +++ b/src/types/DeepStrictMerge.ts @@ -15,25 +15,33 @@ namespace DeepStrictMerge { [key in keyof Target | keyof Source]: key extends keyof Target ? key extends keyof Source ? Target[key] extends object - ? Source[key] extends object - ? Target[key] extends Array - ? Source[key] extends Array - ? Array> // If both are arrays of objects, merge their elements into a new array - : never // If one is an array and the other is not, merging is not possible - : Infer // If both are objects, merge them recursively - : Target[key] // If `Target` is an object but `Source` is not, take `Target`'s value + ? Target[key] extends Date + ? Target[key] // Date is a leaf type, Target wins + : Source[key] extends object + ? Source[key] extends Date + ? Target[key] // Source is Date leaf, Target (non-Date object) wins + : Target[key] extends Array + ? Source[key] extends Array + ? Array> // If both are arrays of objects, merge their elements into a new array + : never // If one is an array and the other is not, merging is not possible + : Infer // If both are objects, merge them recursively + : Target[key] // If `Target` is an object but `Source` is not, take `Target`'s value : Target[key] // If `Target` is not an object, take `Target`'s value : Target[key] // If `key` is only in `Target`, take `Target`'s value : key extends keyof Source ? key extends keyof Target ? Source[key] extends object - ? Target[key] extends object - ? Target[key] extends Array - ? Source[key] extends Array - ? Array> // If both are arrays of objects, merge their elements into a new array - : never // If one is an array and the other is not, merging is not possible - : Infer // If both are objects, merge them recursively - : Source[key] // If `Source` is an object but `Target` is not, take `Source`'s value + ? Source[key] extends Date + ? Target[key] // Date is a leaf type, Target wins + : Target[key] extends object + ? Target[key] extends Date + ? Target[key] // Target is Date leaf, preserve as-is + : Target[key] extends Array + ? Source[key] extends Array + ? Array> // If both are arrays of objects, merge their elements into a new array + : never // If one is an array and the other is not, merging is not possible + : Infer // If both are objects, merge them recursively + : Source[key] // If `Source` is an object but `Target` is not, take `Source`'s value : Source[key] // If `Source` is not an object, take `Source`'s value : Source[key] // If `key` is only in `Source`, take `Source`'s value : never; // If `key` is in neither `Target` nor `Source`, return `never` diff --git a/test/features/DeepStrictMerge.ts b/test/features/DeepStrictMerge.ts index 75a1a46..4e21ded 100644 --- a/test/features/DeepStrictMerge.ts +++ b/test/features/DeepStrictMerge.ts @@ -91,3 +91,30 @@ export function test_types_deep_strict_merge_source_only_nested() { type Answer = Equal; ok(typia.random()); } + +/** + * Tests that DeepStrictMerge preserves Date properties from both Target and Source. + */ +export function test_types_deep_strict_merge_date_preserved() { + type Question = DeepStrictMerge<{ createdAt: Date }, { updatedAt: Date }>; + type Answer = Equal; + ok(typia.random()); +} + +/** + * Tests that DeepStrictMerge preserves Date when both Target and Source have the same Date key. + */ +export function test_types_deep_strict_merge_overlapping_date() { + type Question = DeepStrictMerge<{ date: Date }, { date: Date }>; + type Answer = Equal; + ok(typia.random()); +} + +/** + * Tests that DeepStrictMerge preserves Date in nested objects. + */ +export function test_types_deep_strict_merge_nested_date() { + type Question = DeepStrictMerge<{ a: { createdAt: Date; b: number } }, { a: { updatedAt: Date; c: string } }>; + type Answer = Equal; + ok(typia.random()); +}