Skip to content

Instantly share code, notes, and snippets.

@yoksel
Last active April 8, 2018 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoksel/60971dd0b2ab0cd37fa2632f65e22675 to your computer and use it in GitHub Desktop.
Save yoksel/60971dd0b2ab0cd37fa2632f65e22675 to your computer and use it in GitHub Desktop.
extend.js для typescript
const hasOwnProperty = Object.prototype.hasOwnProperty;
const objToString = Object.prototype.toString;
/**
* Проверяет, что переданный объект является "плоским" (т.е. созданным с помощью "{}"
* или "new Object").
*
* @param {Object} obj
* @returns {Boolean}
*/
function isPlainObject<T>(obj: T): boolean {
const prototype = Object.getPrototypeOf(obj);
return prototype === null ||
prototype === Object.prototype;
}
/**
* Копирует перечислимые свойства одного или нескольких объектов в целевой объект.
*
* @param {Boolean} [deep=false] При значении `true` свойства копируются рекурсивно.
* @param {Object} target Объект для расширения. Он получит новые свойства.
* @param {...Object} objects Объекты со свойствами для копирования. Аргументы со значениями
* `null` или `undefined` игнорируются.
* @returns {Object}
*/
function extend<T, T2, T3>(arg1: T | T2, arg2: T2 | T3, arg3?: T3): T;
function extend<T, T2, T3, T4>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4): T;
function extend<T, T2, T3, T4, T5>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5): T;
function extend<T, T2, T3, T4, T5, T6>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5 | T6, arg6?: T6): T;
function extend<T, T2, T3, T4, T5, T6, T7>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5 | T6, arg6?: T6 | T7, arg7?: T7): T;
function extend<T, T2, T3, T4, T5, T6, T7, T8>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5 | T6, arg6?: T6 | T7, arg7?: T7 | T8, arg8?: T8): T;
function extend<T, T2, T3, T4, T5, T6, T7, T8, T9>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5 | T6, arg6?: T6 | T7, arg7?: T7 | T8, arg8?: T8 | T9, arg9?: T9): T;
function extend<T, T2, T3, T4, T5, T6, T7, T8, T9>(arg1: T | T2, arg2: T2 | T3, arg3?: T3 | T4, arg4?: T4 | T5, arg5?: T5 | T6, arg6?: T6 | T7, arg7?: T7 | T8, arg8?: T8 | T9, arg9?: T9): T {
const args = arguments;
let target = args[0];
let deep: boolean;
let i;
const restrictedTypes = ['null', 'undefined'];
// Проверяем допустимые типы
if (typeof target === 'string' || typeof target === 'number' || target === null || target === undefined) {
throw new Error('Функция extend() ожидает на вход массивы или объекты');
}
// Обрабатываем ситуацию глубокого копирования.
if (typeof target === 'boolean') {
deep = target;
target = <T>args[1];
i = 2;
} else {
deep = false;
i = 1;
}
for (; i < arguments.length; i++) {
const obj = args[i];
if (!obj) {
continue;
}
for (const key in obj) {
if (hasOwnProperty.call(obj, key)) {
const val = obj[key];
const isArray = val && Array.isArray(val);
// Копируем "плоские" объекты и массивы рекурсивно.
if (deep && val && (isPlainObject(val) || isArray)) {
const src = target[key];
let clone;
if (isArray) {
clone = src && Array.isArray(src) ? src : [];
} else {
clone = src && isPlainObject(src) ? src : {};
}
target[key] = extend(deep, clone, val);
} else {
target[key] = val;
}
}
}
}
return target;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment