Skip to content

Commit

Permalink
refactor(ts): Simpler draft / immutable implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate authored and aleclarson committed Apr 17, 2019
1 parent df68c23 commit 7e971b6
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 40 deletions.
3 changes: 1 addition & 2 deletions __tests__/draft.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Draft, DraftArray} from "../dist/immer.js"
import {Draft} from "../dist/immer.js"

// For checking if a type is assignable to its draft type (and vice versa)
declare const toDraft: <T>(value: T) => Draft<T>
Expand All @@ -23,7 +23,6 @@ declare const _: any
// NOTE: As of 3.2.2, everything fails without "extends any"
const $ = <Value extends any>(val: ReadonlyArray<Value>) => {
val = _ as Draft<typeof val>
val = _ as DraftArray<typeof val>
let elem: Value = _ as Draft<Value>
}
}
Expand Down
46 changes: 8 additions & 38 deletions src/immer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,17 @@ type AtomicObject =
| Number
| String

type ArrayMethod = Exclude<keyof [], number>
type Indices<T> = Exclude<keyof T, ArrayMethod>

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

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 never[]
export type Draft<T> = T extends AtomicObject
? T
: T extends ReadonlyArray<any>
? T[number][] extends T
? DraftArray<T>
: DraftTuple<T>
: T extends AtomicObject
: T extends object
? {-readonly [K in keyof T]: Draft<T[K]>}
: T // mostly: unknown & any

/** Convert a mutable type into a readonly type */
export type Immutable<T> = T extends AtomicObject
? T
: T extends object
? {-readonly [P in keyof T]: Draft<T[P]>}
? {readonly [K in keyof T]: Immutable<T[K]>}
: T

export interface Patch {
Expand All @@ -52,26 +42,6 @@ export type Produced<Base, Return> = Return extends void
: Return extends Promise<infer Result>
? Promise<Result extends void ? Base : FromNothing<Result>>
: FromNothing<Return>

type ImmutableArray<T extends ReadonlyArray<any>> = {
[P in Extract<keyof T, number>]: ReadonlyArray<Immutable<T[number]>>
}[Extract<keyof T, number>]

type ImmutableTuple<T extends ReadonlyArray<any>> = {
readonly [P in keyof T]: Immutable<T[P]>
}

/** Convert a mutable type into a readonly type */
export type Immutable<T> = T extends object
? T extends AtomicObject
? T
: T extends ReadonlyArray<any>
? Array<T[number]> extends T
? ImmutableArray<T>
: ImmutableTuple<T>
: {readonly [P in keyof T]: Immutable<T[P]>}
: T

export interface IProduce {
/**
* The `produce` function takes a value and a "recipe function" (whose
Expand Down

0 comments on commit 7e971b6

Please sign in to comment.