[1] Simple

function deepCopy(source: any) {
    if (!source || typeof source !== 'object') {
        return source;
    }
    const targetObj: any = source.constructor === Array ? [] : {};
    for (const key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
            if (source[key] && typeof source[key] === 'object') {
                targetObj[key] = deepCopy(source[key]);
            }
            else {
                targetObj[key] = source[key];
            }
        }
    }
    return targetObj;
}

[1] - 문제점

[2]

function deepCopy(source: any, map = new WeakMap()) {
    // 기본 타입이거나 함수인 경우, 원본 값을 반환
    if (source === null || typeof source !== 'object' || typeof source === 'function') {
        return source;
    }

    // 순환 참조 처리: 이미 복사된 객체가 있다면 그 참조를 반환
    if (map.has(source)) {
        return map.get(source);
    }

    // 특수 객체 처리 (Date와 RegExp)
    let clone: any;
    if (source instanceof Date) {
        clone = new Date(source);
        map.set(source, clone);
        return clone;
    }
    if (source instanceof RegExp) {
        clone = new RegExp(source.source, source.flags);
        map.set(source, clone);
        return clone;
    }

    // 배열이거나 객체인 경우, 적절한 복제본을 생성
    clone = Array.isArray(source) ? [] : {};
    map.set(source, clone);

    // Symbol 속성 포함하여 모든 속성을 복사
    Reflect.ownKeys(source).forEach(key => {
        clone[key] = deepCopy(source[key], map);
    });

    return clone;
}

[3]