Add support for BigInt (#87)

This commit is contained in:
Vlad Frangu 2019-05-04 12:05:23 +03:00 committed by Sindre Sorhus
parent 373605e40d
commit dd2a91dce5
4 changed files with 95 additions and 10 deletions

View file

@ -80,6 +80,11 @@
"extensions": [ "extensions": [
"ts" "ts"
], ],
"globals": [
"BigInt",
"BigInt64Array",
"BigUint64Array"
],
"rules": { "rules": {
"@typescript-eslint/explicit-function-return-type": "off" "@typescript-eslint/explicit-function-return-type": "off"
} }

View file

@ -1,5 +1,4 @@
/// <reference lib="es2017"/> /// <reference lib="esnext"/>
/// <reference lib="esnext.asynciterable"/>
/// <reference lib="dom"/> /// <reference lib="dom"/>
// TODO: Use the `URL` global when targeting Node.js 10 // TODO: Use the `URL` global when targeting Node.js 10
@ -14,6 +13,7 @@ export const enum TypeName {
undefined = 'undefined', undefined = 'undefined',
string = 'string', string = 'string',
number = 'number', number = 'number',
bigint = 'bigint',
symbol = 'symbol', symbol = 'symbol',
Function = 'Function', Function = 'Function',
Generator = 'Generator', Generator = 'Generator',
@ -39,6 +39,8 @@ export const enum TypeName {
Uint32Array = 'Uint32Array', Uint32Array = 'Uint32Array',
Float32Array = 'Float32Array', Float32Array = 'Float32Array',
Float64Array = 'Float64Array', Float64Array = 'Float64Array',
BigInt64Array = 'BigInt64Array',
BigUint64Array = 'BigUint64Array',
ArrayBuffer = 'ArrayBuffer', ArrayBuffer = 'ArrayBuffer',
SharedArrayBuffer = 'SharedArrayBuffer', SharedArrayBuffer = 'SharedArrayBuffer',
DataView = 'DataView', DataView = 'DataView',
@ -77,6 +79,8 @@ function is(value: unknown): TypeName {
return TypeName.string; return TypeName.string;
case 'number': case 'number':
return TypeName.number; return TypeName.number;
case 'bigint':
return TypeName.bigint;
case 'symbol': case 'symbol':
return TypeName.symbol; return TypeName.symbol;
default: default:
@ -115,6 +119,7 @@ const isObject = (value: unknown): value is object => typeof value === 'object';
is.undefined = isOfType<undefined>('undefined'); is.undefined = isOfType<undefined>('undefined');
is.string = isOfType<string>('string'); is.string = isOfType<string>('string');
is.number = isOfType<number>('number'); is.number = isOfType<number>('number');
is.bigint = isOfType<bigint>('bigint');
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
is.function_ = isOfType<Function>('function'); is.function_ = isOfType<Function>('function');
@ -175,6 +180,8 @@ is.int32Array = isObjectOfType<Int32Array>(TypeName.Int32Array);
is.uint32Array = isObjectOfType<Uint32Array>(TypeName.Uint32Array); is.uint32Array = isObjectOfType<Uint32Array>(TypeName.Uint32Array);
is.float32Array = isObjectOfType<Float32Array>(TypeName.Float32Array); is.float32Array = isObjectOfType<Float32Array>(TypeName.Float32Array);
is.float64Array = isObjectOfType<Float64Array>(TypeName.Float64Array); is.float64Array = isObjectOfType<Float64Array>(TypeName.Float64Array);
is.bigint64Array = isObjectOfType<BigInt64Array>(TypeName.BigInt64Array);
is.biguint64Array = isObjectOfType<BigUint64Array>(TypeName.BigUint64Array);
is.arrayBuffer = isObjectOfType<ArrayBuffer>(TypeName.ArrayBuffer); is.arrayBuffer = isObjectOfType<ArrayBuffer>(TypeName.ArrayBuffer);
is.sharedArrayBuffer = isObjectOfType<SharedArrayBuffer>(TypeName.SharedArrayBuffer); is.sharedArrayBuffer = isObjectOfType<SharedArrayBuffer>(TypeName.SharedArrayBuffer);
@ -208,12 +215,13 @@ const primitiveTypeOfTypes = new Set([
'undefined', 'undefined',
'string', 'string',
'number', 'number',
'bigint',
'boolean', 'boolean',
'symbol' 'symbol'
]); ]);
// TODO: This should be able to be `not object` when the `not` operator is out // TODO: This should be able to be `not object` when the `not` operator is out
export type Primitive = null | undefined | string | number | boolean | symbol; export type Primitive = null | undefined | string | number | bigint | boolean | symbol;
is.primitive = (value: unknown): value is Primitive => is.null_(value) || primitiveTypeOfTypes.has(typeof value); is.primitive = (value: unknown): value is Primitive => is.null_(value) || primitiveTypeOfTypes.has(typeof value);
@ -240,10 +248,12 @@ const typedArrayTypes = new Set([
TypeName.Int32Array, TypeName.Int32Array,
TypeName.Uint32Array, TypeName.Uint32Array,
TypeName.Float32Array, TypeName.Float32Array,
TypeName.Float64Array TypeName.Float64Array,
TypeName.BigInt64Array,
TypeName.BigUint64Array
]); ]);
export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
is.typedArray = (value: unknown): value is TypedArray => { is.typedArray = (value: unknown): value is TypedArray => {
const objectType = getObjectType(value); const objectType = getObjectType(value);

View file

@ -2,7 +2,6 @@ import fs from 'fs';
import net from 'net'; import net from 'net';
import Stream from 'stream'; import Stream from 'stream';
import util from 'util'; import util from 'util';
import {URL} from 'url';
import tempy from 'tempy'; import tempy from 'tempy';
import test, {ExecutionContext} from 'ava'; import test, {ExecutionContext} from 'ava';
import {JSDOM} from 'jsdom'; import {JSDOM} from 'jsdom';
@ -10,6 +9,9 @@ import {Subject, Observable} from 'rxjs';
import ZenObservable from 'zen-observable'; import ZenObservable from 'zen-observable';
import is, {TypeName} from '../source'; import is, {TypeName} from '../source';
// eslint-disable-next-line @typescript-eslint/no-require-imports
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL;
const isNode10orHigher = Number(process.versions.node.split('.')[0]) >= 10; const isNode10orHigher = Number(process.versions.node.split('.')[0]) >= 10;
class PromiseSubclassFixture<T> extends Promise<T> {} class PromiseSubclassFixture<T> extends Promise<T> {}
@ -69,6 +71,18 @@ const types = new Map<string, Test>([
], ],
typename: TypeName.number typename: TypeName.number
}], }],
// TODO: Nodejs 10 only
// ['bigint', {
// is: is.bigint,
// fixtures: [
// 1n,
// 0n,
// -0n,
// // eslint-disable-next-line new-cap
// BigInt('1234')
// ],
// typename: TypeName.bigint
// }],
['boolean', { ['boolean', {
is: is.boolean, is: is.boolean,
fixtures: [ fixtures: [
@ -311,6 +325,21 @@ const types = new Map<string, Test>([
], ],
typename: TypeName.Float64Array typename: TypeName.Float64Array
}], }],
// TODO: Nodejs 10 only
// ['bigint64Array', {
// is: is.bigint64Array,
// fixtures: [
// new BigInt64Array()
// ],
// typename: TypeName.BigInt64Array
// }],
// ['biguint64Array', {
// is: is.biguint64Array,
// fixtures: [
// new BigUint64Array()
// ],
// typename: TypeName.BigUint64Array
// }],
['arrayBuffer', { ['arrayBuffer', {
is: is.arrayBuffer, is: is.arrayBuffer,
fixtures: [ fixtures: [
@ -468,6 +497,11 @@ test('is.number', t => {
testType(t, 'number', ['nan', 'integer', 'safeInteger', 'infinite']); testType(t, 'number', ['nan', 'integer', 'safeInteger', 'infinite']);
}); });
// TODO: Nodejs 10 only
// test('is.bigint', t => {
// testType(t, 'bigint');
// });
test('is.boolean', t => { test('is.boolean', t => {
testType(t, 'boolean'); testType(t, 'boolean');
}); });
@ -596,6 +630,15 @@ test('is.float64Array', t => {
testType(t, 'float64Array'); testType(t, 'float64Array');
}); });
// TODO: Nodejs 10 only
// test('is.bigint64Array', t => {
// testType(t, 'bigint64Array');
// });
// test('is.biguint64Array', t => {
// testType(t, 'biguint64Array');
// });
test('is.arrayBuffer', t => { test('is.arrayBuffer', t => {
testType(t, 'arrayBuffer'); testType(t, 'arrayBuffer');
}); });
@ -616,7 +659,7 @@ test('is.directInstanceOf', t => {
}); });
test('is.urlInstance', t => { test('is.urlInstance', t => {
const url = new URL('https://example.com'); const url = new URLGlobal('https://example.com');
t.true(is.urlInstance(url)); t.true(is.urlInstance(url));
t.false(is.urlInstance({})); t.false(is.urlInstance({}));
t.false(is.urlInstance(undefined)); t.false(is.urlInstance(undefined));
@ -626,7 +669,7 @@ test('is.urlInstance', t => {
test('is.urlString', t => { test('is.urlString', t => {
const url = 'https://example.com'; const url = 'https://example.com';
t.true(is.urlString(url)); t.true(is.urlString(url));
t.false(is.urlString(new URL(url))); t.false(is.urlString(new URLGlobal(url)));
t.false(is.urlString({})); t.false(is.urlString({}));
t.false(is.urlString(undefined)); t.false(is.urlString(undefined));
t.false(is.urlString(null)); t.false(is.urlString(null));
@ -638,6 +681,14 @@ test('is.truthy', t => {
t.true(is.truthy(new Set())); t.true(is.truthy(new Set()));
t.true(is.truthy(Symbol('🦄'))); t.true(is.truthy(Symbol('🦄')));
t.true(is.truthy(true)); t.true(is.truthy(true));
t.true(is.truthy(1));
// TODO: Nodejs 10 only
// if (isNode10orHigher) {
// t.true(is.truthy(1n));
// // eslint-disable-next-line new-cap
// t.true(is.truthy(BigInt(1)));
// }
}); });
test('is.falsy', t => { test('is.falsy', t => {
@ -647,6 +698,13 @@ test('is.falsy', t => {
t.true(is.falsy(null)); t.true(is.falsy(null));
t.true(is.falsy(undefined)); t.true(is.falsy(undefined));
t.true(is.falsy(NaN)); t.true(is.falsy(NaN));
// TODO: Nodejs 10 only
// if (isNode10orHigher) {
// t.true(is.falsy(0n));
// // eslint-disable-next-line new-cap
// t.true(is.falsy(BigInt(0)));
// }
}); });
test('is.nan', t => { test('is.nan', t => {
@ -670,6 +728,11 @@ test('is.primitive', t => {
Symbol('🦄') Symbol('🦄')
]; ];
// TODO: Nodejs 10 only
// if (isNode10orHigher) {
// primitives.push(6n);
// }
for (const el of primitives) { for (const el of primitives) {
t.true(is.primitive(el)); t.true(is.primitive(el));
} }
@ -742,6 +805,14 @@ test('is.typedArray', t => {
new Float64Array() new Float64Array()
]; ];
// TODO: Nodejs 10 only
// if (isNode10orHigher) {
// typedArrays.push(
// new BigInt64Array(),
// new BigUint64Array()
// );
// }
for (const item of typedArrays) { for (const item of typedArrays) {
t.true(is.typedArray(item)); t.true(is.typedArray(item));
} }

View file

@ -4,8 +4,7 @@
"outDir": "dist", "outDir": "dist",
"target": "es2017", "target": "es2017",
"lib": [ "lib": [
"es2017", "esnext",
"esnext.asynciterable",
"dom" "dom"
] ]
}, },