All files base.js

88.24% Statements 30/34
100% Branches 21/21
85.71% Functions 12/14
87.88% Lines 29/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92                  12x                   1x     54x           28x         12x   158x           46x 26x 24x   2x   2x           20x   20x 9x 5x   5x 2x   3x 2x   4x 3x   3x 2x     1x   1x           20x       3x 3x   30x        
import nativeTypeMap from './nativeTypeMap';
 
export class BaseType {
  static isOfType(val) {
    console.error(`An isOfType function needs to be defined for "${this.name}"`);
    return false;
  }
 
  static get optional() {
    return optional(this);
  }
}
 
export class UnionType extends BaseType {
  static get types() {
    console.error('This type is meant to be extended with an overrided static `types` property. It\'s suggested to use `Union.ofTypes(...types)` to generate a new union');
    return [];
  }
  static ofTypes(...types) {
    return unionOf(...types);
  }
  static isOfType(val) {
    return this.types.some((type) => type.isOfType(val));
  }
}
 
export class AnyType extends BaseType {
  static isOfType(val) {
    return val !== undefined && val !== null;
  }
}
 
export function optional(type) {
  return class OptionalType extends coerce(type) {
    static isOfType(val) {
      return super.isOfType(val) || val === undefined || val === null;
    }
  };
}
 
export function coerce(type) {
  if (typeof type.isOfType === 'function') {
    if (type.prototype instanceof BaseType) {
      return type;
    } else {
      return class CoercedType extends BaseType {
        static isOfType(val) {
          return type.isOfType(val);
        }
      }
    }
  }
 
  let derivedType = nativeTypeMap.get(type);
 
  if (!derivedType) {
    if (Array.isArray(type)) {
      derivedType = nativeTypeMap.get(Array);
      // Arrays of length 1, all items of the array should be of that type
      if (type.length === 1) {
        derivedType = derivedType.ofType(type[0]);
      // Array of greater lengths, type should be a union of all types
      } else if (type.length > 1) {
        derivedType = derivedType.ofType(unionOf(...type));
      }
    } else if (type.constructor === Object) {
      derivedType = nativeTypeMap.get(Object);
      // If there are keys, add a definition to the object
      if (Object.keys(type).length) {
        derivedType = derivedType.withDefinition(type);
      }
    } else {
      derivedType = class InsatanceOfType extends BaseType {
        static isOfType(val) {
          return val instanceof type;
        }
      };
    }
  }
 
  return derivedType;
}
 
export function unionOf(...unionTypes) {
  const coercedTypes = unionTypes.map(coerce);
  return class DefinedUnionType extends UnionType {
    static get types() {
      return coercedTypes;
    }
  };
}