Enumerate type names (#32)

This commit is contained in:
Mario Nebl 2017-11-19 21:07:24 +01:00 committed by Sindre Sorhus
parent 319982a09c
commit ae3adc9818

View file

@ -1,47 +1,91 @@
import * as util from 'util'; import * as util from 'util';
const toString = Object.prototype.toString; export const enum TypeName {
const getObjectType = (value: any) => toString.call(value).slice(8, -1) as string; null = 'null',
const isOfType = (type: string) => (value: any) => typeof value === type; // tslint:disable-line:strict-type-predicates boolean = 'boolean',
const isObjectOfType = (type: string) => (value: any) => getObjectType(value) === type; undefined = 'undefined',
string = 'string',
number = 'number',
symbol = 'symbol',
Function = 'Function',
Array = 'Array',
Buffer = 'Buffer',
Object = 'Object',
RegExp = 'RegExp',
Date = 'Date',
Error = 'Error',
Map = 'Map',
Set = 'Set',
WeakMap = 'WeakMap',
WeakSet = 'WeakSet',
Int8Array = 'Int8Array',
Uint8Array = 'Uint8Array',
Uint8ClampedArray = 'Uint8ClampedArray',
Int16Array = 'Int16Array',
Uint16Array = 'Uint16Array',
Int32Array = 'Int32Array',
Uint32Array = 'Uint32Array',
Float32Array = 'Float32Array',
Float64Array = 'Float64Array',
ArrayBuffer = 'ArrayBuffer',
SharedArrayBuffer = 'SharedArrayBuffer',
Promise = 'Promise'
}
function is(value: any) { // tslint:disable-line:only-arrow-functions const toString = Object.prototype.toString;
const isOfType = (type: string) => (value: any) => typeof value === type; // tslint:disable-line:strict-type-predicates
const getObjectType = (value: any): TypeName | null => {
const objectName = toString.call(value).slice(8, -1) as string;
if (objectName) {
return objectName as TypeName;
}
return null;
};
const isObjectOfType = (typeName: TypeName) => (value: any) => {
return getObjectType(value) === typeName;
};
function is(value: any): TypeName { // tslint:disable-line:only-arrow-functions
if (value === null) { if (value === null) {
return 'null'; return TypeName.null;
} }
if (value === true || value === false) { if (value === true || value === false) {
return 'boolean'; return TypeName.boolean;
} }
const type = typeof value; const type = typeof value;
if (type === 'undefined') { if (type === 'undefined') {
return 'undefined'; return TypeName.undefined;
} }
if (type === 'string') { if (type === 'string') {
return 'string'; return TypeName.string;
} }
if (type === 'number') { if (type === 'number') {
return 'number'; return TypeName.number;
} }
if (type === 'symbol') { if (type === 'symbol') {
return 'symbol'; return TypeName.symbol;
} }
if (is.function_(value)) { if (is.function_(value)) {
return 'Function'; return TypeName.Function;
} }
if (Array.isArray(value)) { if (Array.isArray(value)) {
return 'Array'; return TypeName.Array;
} }
if (Buffer.isBuffer(value)) { if (Buffer.isBuffer(value)) {
return 'Buffer'; return TypeName.Buffer;
} }
const tagType = getObjectType(value); const tagType = getObjectType(value);
@ -53,7 +97,7 @@ function is(value: any) { // tslint:disable-line:only-arrow-functions
throw new TypeError('Please don\'t use object wrappers for primitive types'); throw new TypeError('Please don\'t use object wrappers for primitive types');
} }
return 'Object'; return TypeName.Object;
} }
namespace is { // tslint:disable-line:no-namespace namespace is { // tslint:disable-line:no-namespace
@ -80,7 +124,7 @@ namespace is { // tslint:disable-line:no-namespace
export const iterable = (value: any) => !nullOrUndefined(value) && function_(value[Symbol.iterator]); export const iterable = (value: any) => !nullOrUndefined(value) && function_(value[Symbol.iterator]);
export const generator = (value: any) => iterable(value) && function_(value.next) && function_(value.throw); export const generator = (value: any) => iterable(value) && function_(value.next) && function_(value.throw);
export const nativePromise = isObjectOfType('Promise'); export const nativePromise = isObjectOfType(TypeName.Promise);
const hasPromiseAPI = (value: any) => const hasPromiseAPI = (value: any) =>
!null_(value) && !null_(value) &&
@ -97,26 +141,26 @@ namespace is { // tslint:disable-line:no-namespace
export const asyncFunction = isFunctionOfType('AsyncFunction'); export const asyncFunction = isFunctionOfType('AsyncFunction');
export const boundFunction = (value: any) => function_(value) && !value.hasOwnProperty('prototype'); export const boundFunction = (value: any) => function_(value) && !value.hasOwnProperty('prototype');
export const regExp = isObjectOfType('RegExp'); export const regExp = isObjectOfType(TypeName.RegExp);
export const date = isObjectOfType('Date'); export const date = isObjectOfType(TypeName.Date);
export const error = isObjectOfType('Error'); export const error = isObjectOfType(TypeName.Error);
export const map = isObjectOfType('Map'); export const map = isObjectOfType(TypeName.Map);
export const set = isObjectOfType('Set'); export const set = isObjectOfType(TypeName.Set);
export const weakMap = isObjectOfType('WeakMap'); export const weakMap = isObjectOfType(TypeName.WeakMap);
export const weakSet = isObjectOfType('WeakSet'); export const weakSet = isObjectOfType(TypeName.WeakSet);
export const int8Array = isObjectOfType('Int8Array'); export const int8Array = isObjectOfType(TypeName.Int8Array);
export const uint8Array = isObjectOfType('Uint8Array'); export const uint8Array = isObjectOfType(TypeName.Uint8Array);
export const uint8ClampedArray = isObjectOfType('Uint8ClampedArray'); export const uint8ClampedArray = isObjectOfType(TypeName.Uint8ClampedArray);
export const int16Array = isObjectOfType('Int16Array'); export const int16Array = isObjectOfType(TypeName.Int16Array);
export const uint16Array = isObjectOfType('Uint16Array'); export const uint16Array = isObjectOfType(TypeName.Uint16Array);
export const int32Array = isObjectOfType('Int32Array'); export const int32Array = isObjectOfType(TypeName.Int32Array);
export const uint32Array = isObjectOfType('Uint32Array'); export const uint32Array = isObjectOfType(TypeName.Uint32Array);
export const float32Array = isObjectOfType('Float32Array'); export const float32Array = isObjectOfType(TypeName.Float32Array);
export const float64Array = isObjectOfType('Float64Array'); export const float64Array = isObjectOfType(TypeName.Float64Array);
export const arrayBuffer = isObjectOfType('ArrayBuffer'); export const arrayBuffer = isObjectOfType(TypeName.ArrayBuffer);
export const sharedArrayBuffer = isObjectOfType('SharedArrayBuffer'); export const sharedArrayBuffer = isObjectOfType(TypeName.SharedArrayBuffer);
export const truthy = (value: any) => Boolean(value); export const truthy = (value: any) => Boolean(value);
export const falsy = (value: any) => !value; export const falsy = (value: any) => !value;
@ -140,23 +184,31 @@ namespace is { // tslint:disable-line:no-namespace
// From: https://github.com/sindresorhus/is-plain-obj/blob/master/index.js // From: https://github.com/sindresorhus/is-plain-obj/blob/master/index.js
let prototype; let prototype;
return getObjectType(value) === 'Object' && return getObjectType(value) === TypeName.Object &&
(prototype = Object.getPrototypeOf(value), prototype === null || // tslint:disable-line:ban-comma-operator (prototype = Object.getPrototypeOf(value), prototype === null || // tslint:disable-line:ban-comma-operator
prototype === Object.getPrototypeOf({})); prototype === Object.getPrototypeOf({}));
}; };
const typedArrayTypes = new Set([ const typedArrayTypes = new Set([
'Int8Array', TypeName.Int8Array,
'Uint8Array', TypeName.Uint8Array,
'Uint8ClampedArray', TypeName.Uint8ClampedArray,
'Int16Array', TypeName.Int16Array,
'Uint16Array', TypeName.Uint16Array,
'Int32Array', TypeName.Int32Array,
'Uint32Array', TypeName.Uint32Array,
'Float32Array', TypeName.Float32Array,
'Float64Array' TypeName.Float64Array
]); ]);
export const typedArray = (value: any) => typedArrayTypes.has(getObjectType(value)); export const typedArray = (value: any) => {
const objectType = getObjectType(value);
if (objectType === null) {
return false;
}
return typedArrayTypes.has(objectType);
};
const isValidLength = (value: any) => safeInteger(value) && value > -1; const isValidLength = (value: any) => safeInteger(value) && value > -1;
export const arrayLike = (value: any) => !nullOrUndefined(value) && !function_(value) && isValidLength(value.length); export const arrayLike = (value: any) => !nullOrUndefined(value) && !function_(value) && isValidLength(value.length);