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.
74 lines
2.0 KiB
74 lines
2.0 KiB
/** |
|
* 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 defaultObjectStatePropSetter = <S extends BaseObject>( |
|
...[, result, key, value]: Parameters<ObjectStatePropSetter<S>> |
|
): ReturnType<ObjectStatePropSetter<S>> => { |
|
if (value !== undefined) { |
|
result[key] = value; |
|
} |
|
}; |
|
|
|
const buildObjectStateSetterCallback = |
|
<S extends BaseObject>( |
|
key: keyof S, |
|
value?: S[keyof S], |
|
{ |
|
guard = () => true, |
|
set = defaultObjectStatePropSetter, |
|
}: BuildObjectStateSetterCallbackOptions<S> = {}, |
|
): BuildObjectStateSetterCallbackReturnType<S> => |
|
(previous: S): S => { |
|
const { [key]: toReplace, ...restPrevious } = previous; |
|
const result = { ...restPrevious } as S; |
|
|
|
if (guard(previous, key, value)) { |
|
set(previous, result, key, value); |
|
} |
|
|
|
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 const buildRegExpObjectStateSetterCallback = |
|
<S extends BaseObject>( |
|
re: RegExp, |
|
value?: S[keyof S], |
|
{ |
|
set = defaultObjectStatePropSetter, |
|
}: Pick<BuildObjectStateSetterCallbackOptions<S>, 'set'> = {}, |
|
) => |
|
(previous: S): S => { |
|
const result: S = {} as S; |
|
|
|
Object.keys(previous).forEach((key) => { |
|
const k = key as keyof S; |
|
|
|
if (re.test(key)) { |
|
set(previous, result, k, value); |
|
} else { |
|
result[k] = previous[k]; |
|
} |
|
}); |
|
|
|
return result; |
|
}; |
|
|
|
export default buildObjectStateSetterCallback;
|
|
|