You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.0 KiB
69 lines
2.0 KiB
// Project: Immutability helper |
|
// TypeScript Version: 2.9 |
|
|
|
export default update; |
|
|
|
declare function update<T, C extends CustomCommands<object> = never>( |
|
target: T, |
|
spec: Spec<T, C>, |
|
): T; |
|
|
|
declare namespace update { |
|
function newContext(): typeof update; |
|
function extend<T>( |
|
command: string, |
|
handler: (param: any, old: T) => T, |
|
): void; |
|
} |
|
|
|
// Usage with custom commands is as follows: |
|
// |
|
// interface MyCommands { |
|
// $foo: string; |
|
// } |
|
// |
|
// update<Foo, CustomCommands<MyCommands>>(..., { $foo: "bar" }); |
|
// |
|
// It is suggested that if you use custom commands frequently, you wrap and re-export a |
|
// properly-typed version of `update`: |
|
// |
|
// function myUpdate<T>(object: T, spec: Spec<T, CustomCommands<MyCommands>>) { |
|
// return update(object, spec); |
|
// } |
|
// |
|
// See https://github.com/kolodny/immutability-helper/pull/108 for explanation of why this |
|
// type exists. |
|
export type CustomCommands<T> = T & { __noInferenceCustomCommandsBrand: any }; |
|
|
|
export type Spec<T, C extends CustomCommands<object> = never> = |
|
| ( |
|
T extends (Array<infer U> | ReadonlyArray<infer U>) ? ArraySpec<U, C> : |
|
T extends (Map<infer K, infer V> | ReadonlyMap<infer K, infer V>) ? MapSpec<K, V> : |
|
T extends (Set<infer U> | ReadonlySet<infer U>) ? SetSpec<U> : |
|
T extends object ? ObjectSpec<T, C> : |
|
never |
|
) |
|
| { $set: T } |
|
| { $apply: (v: T) => T } |
|
| ((v: T) => T) |
|
| (C extends CustomCommands<infer O> ? O : never); |
|
|
|
type ArraySpec<T, C extends CustomCommands<object>> = |
|
| { $push: T[] } |
|
| { $unshift: T[] } |
|
| { $splice: Array<[number] | [number, number] | [number, number, T]> } |
|
| { [index: string]: Spec<T, C> }; // Note that this does not type check properly if index: number. |
|
|
|
type MapSpec<K, V> = |
|
| { $add: Array<[K, V]> } |
|
| { $remove: K[] }; |
|
|
|
type SetSpec<T> = |
|
| { $add: T[] } |
|
| { $remove: T[] }; |
|
|
|
type ObjectSpec<T, C extends CustomCommands<object>> = |
|
| { $toggle: Array<keyof T> } |
|
| { $unset: Array<keyof T> } |
|
| { $merge: Partial<T> } |
|
| { [K in keyof T]?: Spec<T[K], C> };
|
|
|