Skip to content

Instantly share code, notes, and snippets.

@wilsoncook
Last active July 16, 2020 13:33

Revisions

  1. wilsoncook revised this gist Jul 16, 2020. 1 changed file with 8 additions and 2 deletions.
    10 changes: 8 additions & 2 deletions immutableDefaultsDeep.ts
    Original file line number Diff line number Diff line change
    @@ -3,16 +3,22 @@
    * Benefits: unlike fp.defaultsDeep(), we don't deep clone target to get the real immutable.
    * @param target target
    * @param source source
    * @param options.ignoreArray whether append elements to array
    */
    export function immutableDefaultsDeep(target: any, source: any) {
    export function immutableDefaultsDeep(target: any, source: any, options?: { ignoreArray?: boolean }): any {
    const targetType = typeof target;
    const sourceType = typeof source;

    // non-empty object or array, append value recursively
    if (targetType === 'object' && targetType === sourceType && target !== null && source !== null) {
    // don't append elements to array
    if (options?.ignoreArray && Array.isArray(target)) {
    return target;
    }

    let newTarget = target;
    Object.keys(source).forEach(key => {
    const subTarget = immutableDefaultsDeep(newTarget[key], source[key]);
    const subTarget = immutableDefaultsDeep(newTarget[key], source[key], options);
    if (subTarget !== newTarget[key]) {
    if (Array.isArray(newTarget)) {
    newTarget = [...newTarget];
  2. wilsoncook revised this gist Jul 16, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion immutableDefaultsDeep.ts
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ export function immutableDefaultsDeep(target: any, source: any) {
    if (targetType === 'object' && targetType === sourceType && target !== null && source !== null) {
    let newTarget = target;
    Object.keys(source).forEach(key => {
    const subTarget = immutableDefaultDeep(newTarget[key], source[key]);
    const subTarget = immutableDefaultsDeep(newTarget[key], source[key]);
    if (subTarget !== newTarget[key]) {
    if (Array.isArray(newTarget)) {
    newTarget = [...newTarget];
  3. wilsoncook renamed this gist Jul 16, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion immutableDefaultDeep.ts → immutableDefaultsDeep.ts
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    * @param target target
    * @param source source
    */
    export function immutableDefaultDeep(target: any, source: any) {
    export function immutableDefaultsDeep(target: any, source: any) {
    const targetType = typeof target;
    const sourceType = typeof source;

  4. wilsoncook created this gist Jul 16, 2020.
    43 changes: 43 additions & 0 deletions immutableDefaultDeep.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    /**
    * Fill target with default values by source via immutable
    * Benefits: unlike fp.defaultsDeep(), we don't deep clone target to get the real immutable.
    * @param target target
    * @param source source
    */
    export function immutableDefaultDeep(target: any, source: any) {
    const targetType = typeof target;
    const sourceType = typeof source;

    // non-empty object or array, append value recursively
    if (targetType === 'object' && targetType === sourceType && target !== null && source !== null) {
    let newTarget = target;
    Object.keys(source).forEach(key => {
    const subTarget = immutableDefaultDeep(newTarget[key], source[key]);
    if (subTarget !== newTarget[key]) {
    if (Array.isArray(newTarget)) {
    newTarget = [...newTarget];
    newTarget[key] = subTarget;
    } else {
    newTarget = { ...newTarget, [key]: subTarget };
    }
    }
    });
    return newTarget;
    }

    // target is undefined, return source
    if (targetType === 'undefined') {
    return source;
    }

    // others: return target
    // 1.target is object && typeof target !== typeof source
    // 2.target is null
    // 3.target is number
    // 4.target is string
    // 5.target is symbol
    // 6.target is function
    // 7.target is boolean
    // 8.target is bigint
    return target;
    }