Skip to content

Commit

Permalink
fix: skip ReadonlyMap and ReadonlySet types when not available (#653).
Browse files Browse the repository at this point in the history
…Fixes #624
  • Loading branch information
phryneas committed Oct 20, 2020
1 parent 33a305b commit 12f4cf8
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions src/types/types-external.ts
Expand Up @@ -17,19 +17,36 @@ type AtomicObject =
| Number
| String

/**
* If the lib "ES2105.collections" is not included in tsconfig.json,
* types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere)
* or `{}` (from the node types), in both cases entering an infite recursion in
* pattern matching type mappings
* This type can be used to cast these types to `void` in these cases.
*/
export type IfAvailable<T, Fallback = void> =
// fallback if any
true | false extends (T extends never
? true
: false)
? Fallback // fallback if empty type
: keyof T extends never
? Fallback // original type
: T

/**
* These should also never be mapped but must be tested after regular Map and
* Set
*/
type WeakReferences = WeakMap<any, any> | WeakSet<any>
type WeakReferences = IfAvailable<WeakMap<any, any>> | IfAvailable<WeakSet<any>>

export type WritableDraft<T> = {-readonly [K in keyof T]: Draft<T[K]>}

export type Draft<T> = T extends AtomicObject
? T
: T extends ReadonlyMap<infer K, infer V> // Map extends ReadonlyMap
: T extends IfAvailable<ReadonlyMap<infer K, infer V>> // Map extends ReadonlyMap
? Map<Draft<K>, Draft<V>>
: T extends ReadonlySet<infer V> // Set extends ReadonlySet
: T extends IfAvailable<ReadonlySet<infer V>> // Set extends ReadonlySet
? Set<Draft<V>>
: T extends WeakReferences
? T
Expand All @@ -40,9 +57,9 @@ export type Draft<T> = T extends AtomicObject
/** Convert a mutable type into a readonly type */
export type Immutable<T> = T extends AtomicObject
? T
: T extends ReadonlyMap<infer K, infer V> // Map extends ReadonlyMap
: T extends IfAvailable<ReadonlyMap<infer K, infer V>> // Map extends ReadonlyMap
? ReadonlyMap<Immutable<K>, Immutable<V>>
: T extends ReadonlySet<infer V> // Set extends ReadonlySet
: T extends IfAvailable<ReadonlySet<infer V>> // Set extends ReadonlySet
? ReadonlySet<Immutable<V>>
: T extends WeakReferences
? T
Expand Down

0 comments on commit 12f4cf8

Please sign in to comment.