kakasoo / kakasoo/DeepStrictTypes

[FEAT] Add `DeepReadonly<T>` type

Open
#51 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
64
Forks
2
PR merge metrics
No merged PRs in 30d

Description

# Feature Request

- [ ] Extensions of existing features
- [x] Propose a type that didn't exist before

**Type Expectation**

A `DeepReadonly` type is needed that recursively converts all properties of objects and arrays to `readonly`. Since this library provides "deep + strict" type manipulation, `DeepReadonly` is a natural extension.

**Example Type**

```typescript
type Input = {
a: number;
b: {
c: string;
d: { e: boolean }[];
};
};

type Result = DeepReadonly;
// Expected:
// {
// readonly a: number;
// readonly b: {
// readonly c: string;
// readonly d: readonly { readonly e: boolean }[];
// };
// }
```

**Proposed Solution**

Create `src/types/DeepReadonly.ts` with the following rules:

1. Add `readonly` modifier to all properties
2. Convert arrays to `readonly T[]`
3. Do not recurse into `Date` types (existing library convention)
4. Preserve branded types (do not unbrand before processing)
5. Add re-export to `src/types/index.ts`

**Use Case**

- Enforce immutability on API response objects to prevent accidental mutation
- Guarantee readonly state in Redux/Zustand store types
- Provide type definitions for the deep version of `Object.freeze`

**Test Requirements**

All changes must include the following tests:

1. **Backward Compatibility**
- All existing tests must pass; the new type must not affect existing types

2. **Feature Verification**
- Simple object readonly conversion
- Nested object readonly conversion
- Array to readonly array
- Objects inside arrays are also readonly
- Date type preserved (not made readonly)
- Already readonly types remain unchanged (idempotency)

3. **Complex Type Stability**
- 3+ levels of nesting (`{ a: { b: { c: { d: number } } } }`)
- 2D arrays (`{ matrix: number[][] }`)
- Arrays inside objects inside arrays (`{ items: { tags: string[] }[] }`)
- Tuple types (`[string, { a: number }]`)
- Optional property preservation (`{ a?: number }` → `{ readonly a?: number }`)
- Union types (`{ a: string | null }`)
- Branded types (`{ id: number & { __brand: 'ID' } }`)
- `any`, `never`, `unknown` properties

**How to verify:**
```bash
npm run build:test && npm run test
npm run prettier
```

Contributor guide

Open the contributing guide

Research direction

Start by reviewing existing deep and strict type utilities, then create src/types/DeepReadonly.ts and inspect src/types/index.ts for the re-export pattern. Add tests for recursive objects, arrays, tuples, dates, branded and edge-case types, then run npm run build:test && npm run test and npm run prettier; done means all listed cases pass without breaking existing tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.