Bug Report
Description
In DeepDateToString, DeepStrictMerge, DeepMerge, and DeepStrictUnbrand, when a readonly array is provided as input, the readonly modifier is lost in the output type. Since type safety is the core focus of this library, loss of modifier information is a bug.
Type Issue Example
When a readonly array is provided as input, the output is converted to a mutable Array.
Type Input
// === DeepDateToString ===
type Input1 = readonly { date: Date }[];
type Result1 = DeepDateToString<Input1>;
// Expected: readonly { date: string }[]
// Actual: { date: string }[] (readonly lost)
// === DeepStrictMerge ===
type Target = readonly { a: number }[];
type Source = readonly { b: string }[];
type Result2 = DeepStrictMerge<Target, Source>;
// Expected: readonly { a: number; b: string }[]
// Actual: { a: number; b: string }[] (readonly lost)
// === DeepStrictUnbrand ===
type Input3 = readonly { a: number & { __brand: 'ID' } }[];
type Result3 = DeepStrictUnbrand<Input3>;
// Expected: readonly { a: number }[]
// Actual: { a: number }[] (readonly lost)
Affected Files
| File |
Line |
Issue |
src/types/DeepDateToString.ts |
29-30 |
Only matches Array<infer I>, no readonly array branch |
src/types/DeepStrictMerge.ts |
13-15 |
Only matches Array<infer TE>, no readonly array branch |
src/types/DeepMerge.ts |
66-73 |
Same pattern |
src/types/DeepStrictUnbrand.ts |
56-68 |
Only matches Array<infer I>, no readonly array branch |
Fix
Add a readonly (infer I)[] branch after each Array<infer I> branch to handle readonly arrays separately. This pattern is already used in DeepStrictObjectKeys:
// DeepStrictObjectKeys.ts:109 (existing reference pattern)
: DeepStrictUnbrand<Target> extends readonly (infer Element)[]
Test Requirements
All changes must include the following tests:
-
Backward Compatibility
- All existing mutable array tests must pass (
npm run build:test && npm run test)
- Add tests to verify that existing type behavior remains unchanged
-
Fix Verification
- For each type, verify
readonly is preserved when inputting a readonly array using the Equal<Question, Answer> pattern
-
Complex Type Stability
readonly { nested: { deep: Date } }[] (readonly + nesting + Date)
readonly [{ a: 1 }, { b: 2 }] (readonly tuple)
readonly { a: number & MinLength<1> }[] (readonly + branded)
readonly (readonly { a: 1 }[])[] (2D readonly array)
readonly { items: readonly { date: Date }[] }[] (nested readonly arrays)
How to verify:
npm run build:test && npm run test
npm run prettier
Bug Report
Description
In
DeepDateToString,DeepStrictMerge,DeepMerge, andDeepStrictUnbrand, when areadonlyarray is provided as input, thereadonlymodifier is lost in the output type. Since type safety is the core focus of this library, loss of modifier information is a bug.Type Issue Example
When a
readonlyarray is provided as input, the output is converted to a mutableArray.Type Input
Affected Files
src/types/DeepDateToString.tsArray<infer I>, noreadonlyarray branchsrc/types/DeepStrictMerge.tsArray<infer TE>, noreadonlyarray branchsrc/types/DeepMerge.tssrc/types/DeepStrictUnbrand.tsArray<infer I>, noreadonlyarray branchFix
Add a
readonly (infer I)[]branch after eachArray<infer I>branch to handlereadonlyarrays separately. This pattern is already used inDeepStrictObjectKeys:Test Requirements
All changes must include the following tests:
Backward Compatibility
npm run build:test && npm run test)Fix Verification
readonlyis preserved when inputting areadonlyarray using theEqual<Question, Answer>patternComplex Type Stability
readonly { nested: { deep: Date } }[](readonly + nesting + Date)readonly [{ a: 1 }, { b: 2 }](readonly tuple)readonly { a: number & MinLength<1> }[](readonly + branded)readonly (readonly { a: 1 }[])[](2D readonly array)readonly { items: readonly { date: Date }[] }[](nested readonly arrays)How to verify: