Skip to content

Commit

Permalink
fix(ts): improve Draft<T> with generics
Browse files Browse the repository at this point in the history
And other small improvements.

Fixes #272
  • Loading branch information
aleclarson committed Dec 18, 2018
1 parent 8666d32 commit cc08cb7
Showing 1 changed file with 14 additions and 24 deletions.
38 changes: 14 additions & 24 deletions src/immer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,27 @@ type AtomicObject =
| Number
| String

/** Use type inference to know when an array is finite */
type IsFinite<T extends any[]> = T extends never[]
? true
: T extends ReadonlyArray<infer U>
? (U[] extends T ? false : true)
: true

export type DraftObject<T> = T extends object
? T extends AtomicObject
? T
: {-readonly [P in keyof T]: Draft<T[P]>}
: T
type ArrayMethod = Exclude<keyof [], number>
type Indices<T> = Exclude<keyof T, ArrayMethod>

export type DraftArray<T> = Array<
T extends ReadonlyArray<any>
? {[P in keyof T]: Draft<T>}[keyof T]
: DraftObject<T>
export type DraftArray<T extends ReadonlyArray<any>> = Array<
{[P in Indices<T>]: Draft<T[P]>}[Indices<T>]
>

export type DraftTuple<T extends any[]> = {
[P in keyof T]: T[P] extends T[number] ? Draft<T[P]> : never
export type DraftTuple<T extends ReadonlyArray<any>> = {
[P in keyof T]: P extends Indices<T> ? Draft<T[P]> : never
}

export type Draft<T> = T extends any[]
? IsFinite<T> extends true
? DraftTuple<T>
: DraftArray<T[number]>
export type Draft<T> = T extends never[]
? T
: T extends ReadonlyArray<any>
? DraftArray<T[number]>
? T[number][] extends T
? DraftArray<T>
: DraftTuple<T>
: T extends AtomicObject
? T
: T extends object
? DraftObject<T>
? {-readonly [P in keyof T]: Draft<T[P]>}
: T

export interface Patch {
Expand Down

0 comments on commit cc08cb7

Please sign in to comment.