用typescript重写常用的js utils方法

309 阅读2分钟

1.判断是否是boolean类型

const isBoolean = (value: unknown): value is boolean =>typeof value === 'boolean';

2.判断是否是null或者undefiend

const isNullOrUndefined = (value: unknown): value is null | undefined =>value == null;

3.判断是否是字符串

const isString = (value: unknown): value is string => typeof value === 'string';

4.是否是原始数据类型

type Primative = null | undefined | number | bigint | boolean | string | symbol;

const isObjectType = (value: unknown) => typeof value === 'object';

const isPrimative = (value: unknown): value is Primative => {
  return isNullOrUndefined(value) || !isObjectType(value);
};

5.是否是正则

const isRegExp = (value: unknown): value is RegExp => value instanceof RegExp;

6.是否是日期对象

const isObjectDate = function isObjectDate(value: unknown): value is Date {
  return value instanceof Date;
};

7.是否是对象

const isObject = function isObject<T extends object>(
  value: unknown,
): value is T {
  return (
    !isObjectDate(value) &&
    !isNullOrUndefined(value) &&
    !Array.isArray(value) &&
    isObjectType(value)
  );

8.是否是纯对象

const isPlainObject = function isPlainObject(value: unknown) {
  if (!isObject(value)) {
    return false;
  }
  let protoType = Object.getPrototypeOf(value);
  return protoType === null || protoType === Object.prototype;
};

9.是否是空对象

type EmptyObject = { [key: string]: never };
//是否是空对象
const isEmptyObject = function isEmptyObject(
  value: unknown,
): value is EmptyObject {
  return isObject(value) && !Object.keys(value).length;
};

10.判断是否是函数

const isFunction = (value: unknown): value is Function =>typeof value === 'function' && typeof obj.nodeType !== 'number';

11.判断数据类型

type ObjectType = { [key: string]: string };
let obj: ObjectType = {};
[
  'Number',
  'String',
  'Boolean',
  'null',
  'undefined',
  'Bigint',
  'Symbol',
  'Array',
  'Object',
  'Date',
  'RegExp',
  'Function',
].forEach((key: string) => {
  obj[`[object ${key}]`] = key.toLowerCase();
});
const toType = (type: unknown): string => {
  return type === null && /^(function|object)$/i.test(typeof type)
    ? obj[Object.prototype.toString.call(type)]
    : typeof type;
};

12.浅克隆

const shallowClone = <T extends Record<keyof T, any>>(data: any): T => {
  let type = toType(data);
  let ctor = null;
  if (data == null) {
    return data;
  }
  ctor = data.constructor;
  if (type == null) return data;
  if (/^(symbol|bigint)$/i.test(type)) {
    return Object(type);
  }
  if (/^(regexp|date)$/i.test(type)) {
    return new ctor(type);
  }
  if (/^(function)$/i.test(type)) {
    return data;
  }
  if (isPlainObject(data)) {
    let result = new ctor();
    for (let item in data) {
      result[item] = data[item];
    }
    return result;
  }
  if (type === 'array') {
    let result = new ctor();
    for (let i = 0; i < data.length; i++) {
      result[i] = data[i];
    }
    return result;
  }
  return data;
};

13.深度克隆

const deepClone = <T extends Record<keyof T, any>>(
  data: any,
  cache = [],
): any => {
  let type = toType(data);
  let ctor = null;
  if (!isPlainObject(data) && type !== 'array') {
    return shallowClone(data);
  }
  cache = Array.isArray(cache) ? cache : [];
  if (cache.indexOf(data as never) > -1) {
    return data;
  }
  cache.push(data as never);
  ctor = data.constructor;
  let result = new ctor();
  if (isPlainObject(data)) {
    for (let item in data) {
      result[item] = deepClone(data[item]);
    }
    return result;
  }
  if (type === 'array') {
    for (let i = 0; i < data.length; i++) {
      result[i] = deepClone(data[i]);
    }
    return result;
  }
};

14.深度合并对象

const deepMerge = <
  T extends Record<keyof T, any>,
  U extends Record<keyof U, any>
>(
  target: T,
  source: U,
): T & U => {
  if (isPrimative(target) || isPrimative(source)) {
    return source;
  }
  for (let key in source) {
    let sourceValue = source[key];
    let targetValue = target[key];
    try {
      (isObject(targetValue) && isObject(sourceValue)) ||
      (Array.isArray(targetValue) && Array.isArray(sourceValue))
        ? deepMerge(targetValue, sourceValue)
        : sourceValue;
    } catch (err) {
      console.log(err);
    }
  }
  return target;
};

15.浅比较

const shallowEqual = (object1: any, object2: any) => {
  if (object1 === object2) {
    return true;
  }
  if (isPrimative(object1) || isPrimative(object2)) {
    return object2 === object1;
  }
  let length1 = Object.keys(object1);
  let length2 = Object.keys(object2);
  if (length1 !== length2) {
    return false;
  }
  for (let key in object1) {
    if (!object2.hasOwnProperty(key) || object2[key] !== object1[key]) {
      return false;
    }
  }
  return true;
};

16.深度比较

const deepEqual = (object1: any, object2: any) => {
  if (object1 === object2) {
    return true;
  }
  if (isPrimative(object1) || isPrimative(object2)) {
    return object2 === object1;
  }
  let length1 = Object.keys(object1);
  let length2 = Object.keys(object2);
  if (length1 !== length2) {
    return false;
  }
  for (let key in object1) {
    if (!object2.include(key)) {
      return false;
    }
    if (
      (isObject(object1[key]) && isObject(object2[key])) ||
      (Array.isArray(object1[key]) && Array.isArray(object2[key]))
        ? shallowEqual(object1[key], object2[key])
        : object1[key!] == object2[key]
    ) {
      return false;
    }
  }
  return true;
};

17.转换成数组

function toArray<T>(arr: T | readonly T[]): T[] {
  if (arr === undefined || arr === null) {
    return [];
  }
  return (Array.isArray(arr) ? arr : [arr]) as T[];
}