parent
b99ac243ab
commit
23ea09ed35
7 changed files with 102 additions and 44 deletions
@ -1,13 +1,46 @@ |
|||||||
|
/** |
||||||
|
* Checks whether specified `key` is unset in given object. Always returns |
||||||
|
* `true` when overwrite is allowed. |
||||||
|
*/ |
||||||
|
const checkUnset = <S extends BaseObject>( |
||||||
|
obj: S, |
||||||
|
key: keyof S, |
||||||
|
{ isOverwrite = false }: { isOverwrite?: boolean } = {}, |
||||||
|
): boolean => !(key in obj) || isOverwrite; |
||||||
|
|
||||||
const buildObjectStateSetterCallback = |
const buildObjectStateSetterCallback = |
||||||
<S extends Record<string, unknown>>(key: keyof S, value?: S[keyof S]) => |
<S extends BaseObject>( |
||||||
({ [key]: toReplace, ...restPrevious }: S): S => { |
key: keyof S, |
||||||
|
value?: S[keyof S], |
||||||
|
{ |
||||||
|
guard, |
||||||
|
set = (o, k, v) => { |
||||||
|
if (v !== undefined) { |
||||||
|
o[k] = v; |
||||||
|
} |
||||||
|
}, |
||||||
|
}: BuildObjectStateSetterCallbackOptions<S> = {}, |
||||||
|
): BuildObjectStateSetterCallbackReturnType<S> => |
||||||
|
(previous: S): S => { |
||||||
|
const { [key]: toReplace, ...restPrevious } = previous; |
||||||
const result = { ...restPrevious } as S; |
const result = { ...restPrevious } as S; |
||||||
|
|
||||||
if (value !== undefined) { |
if (guard?.call(null, previous, key, value)) { |
||||||
result[key] = value; |
set(result, key, value); |
||||||
} |
} |
||||||
|
|
||||||
return result; |
return result; |
||||||
}; |
}; |
||||||
|
|
||||||
|
export const buildProtectedObjectStateSetterCallback = <S extends BaseObject>( |
||||||
|
key: keyof S, |
||||||
|
value?: S[keyof S], |
||||||
|
{ |
||||||
|
isOverwrite, |
||||||
|
guard = (o, k) => checkUnset(o, k, { isOverwrite }), |
||||||
|
set, |
||||||
|
}: BuildObjectStateSetterCallbackOptions<S> = {}, |
||||||
|
): BuildObjectStateSetterCallbackReturnType<S> => |
||||||
|
buildObjectStateSetterCallback(key, value, { isOverwrite, guard, set }); |
||||||
|
|
||||||
export default buildObjectStateSetterCallback; |
export default buildObjectStateSetterCallback; |
||||||
|
@ -0,0 +1,23 @@ |
|||||||
|
type BaseObject<T = unknown> = Record<number | string | symbol, T>; |
||||||
|
|
||||||
|
type ObjectStatePropGuard<S extends BaseObject> = ( |
||||||
|
previous: S, |
||||||
|
key: keyof S, |
||||||
|
value?: S[keyof S], |
||||||
|
) => boolean; |
||||||
|
|
||||||
|
type ObjectStatePropSetter<S extends BaseObject> = ( |
||||||
|
result: S, |
||||||
|
key: keyof S, |
||||||
|
value?: S[keyof S], |
||||||
|
) => void; |
||||||
|
|
||||||
|
type BuildObjectStateSetterCallbackOptions<S extends BaseObject> = { |
||||||
|
guard?: ObjectStatePropGuard<S>; |
||||||
|
isOverwrite?: boolean; |
||||||
|
set?: ObjectStatePropSetter<S>; |
||||||
|
}; |
||||||
|
|
||||||
|
type BuildObjectStateSetterCallbackReturnType<S extends BaseObject> = ( |
||||||
|
previous: S, |
||||||
|
) => S; |
Loading…
Reference in new issue