diff --git a/package.json b/package.json
index cd35b89..f45f2f3 100644
--- a/package.json
+++ b/package.json
@@ -14,9 +14,8 @@
"node": ">=6"
},
"scripts": {
- "lint": "tslint --format stylish --project .",
"build": "del dist && tsc",
- "test": "npm run lint && ava",
+ "test": "xo && ava",
"prepublishOnly": "npm run build"
},
"files": [
@@ -47,20 +46,19 @@
"types"
],
"devDependencies": {
- "@sindresorhus/tsconfig": "^0.2.0",
- "@types/jsdom": "^11.12.0",
- "@types/node": "^10.12.21",
+ "@sindresorhus/tsconfig": "^0.3.0",
+ "@types/jsdom": "^12.2.3",
+ "@types/node": "^11.12.2",
"@types/tempy": "^0.2.0",
"@types/zen-observable": "^0.8.0",
- "ava": "^1.2.0",
+ "@typescript-eslint/eslint-plugin": "^1.5.0",
+ "ava": "^1.4.1",
"del-cli": "^1.1.0",
"jsdom": "^11.6.2",
"rxjs": "^6.4.0",
"tempy": "^0.2.1",
- "ts-node": "^8.0.2",
- "tslint": "^5.9.1",
- "tslint-xo": "^0.10.0",
- "typescript": "^3.3.1",
+ "ts-node": "^8.0.3",
+ "typescript": "^3.4.1",
"zen-observable": "^0.8.8"
},
"types": "dist",
@@ -74,5 +72,14 @@
"require": [
"ts-node/register"
]
+ },
+ "xo": {
+ "extends": "xo-typescript",
+ "extensions": [
+ "ts"
+ ],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": "off"
+ }
}
}
diff --git a/source/index.ts b/source/index.ts
index cfd16ed..64943ab 100644
--- a/source/index.ts
+++ b/source/index.ts
@@ -4,10 +4,10 @@
///
// TODO: Use the `URL` global when targeting Node.js 10
-// tslint:disable-next-line
+// eslint-disable-next-line @typescript-eslint/no-require-imports
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL;
-export type Class = new(...args: any[]) => T;
+export type Class = new (...args: any[]) => T;
export const enum TypeName {
null = 'null',
@@ -46,7 +46,7 @@ export const enum TypeName {
URL = 'URL'
}
-const toString = Object.prototype.toString;
+const {toString} = Object.prototype;
const isOfType = (type: string) => (value: unknown): value is T => typeof value === type;
const getObjectType = (value: unknown): TypeName | undefined => {
@@ -55,12 +55,11 @@ const getObjectType = (value: unknown): TypeName | undefined => {
return objectName as TypeName;
}
- return;
+ return undefined;
};
const isObjectOfType = (type: TypeName) => (value: unknown): value is T => getObjectType(value) === type;
-// tslint:disable-next-line: no-use-before-declare
function is(value: unknown): TypeName {
switch (value) {
case null:
@@ -111,14 +110,15 @@ function is(value: unknown): TypeName {
return TypeName.Object;
}
-// tslint:disable-next-line: strict-type-predicates
const isObject = (value: unknown): value is object => typeof value === 'object';
is.undefined = isOfType('undefined');
is.string = isOfType('string');
is.number = isOfType('number');
+
+// eslint-disable-next-line @typescript-eslint/ban-types
is.function_ = isOfType('function');
-// tslint:disable-next-line: strict-type-predicates
+
is.null_ = (value: unknown): value is null => value === null;
is.class_ = (value: unknown): value is Class => is.function_(value) && value.toString().startsWith('class ');
is.boolean = (value: unknown): value is boolean => value === true || value === false;
@@ -133,7 +133,10 @@ is.buffer = (value: unknown): value is Buffer => !is.nullOrUndefined(value) && !
is.nullOrUndefined = (value: unknown): value is null | undefined => is.null_(value) || is.undefined(value);
is.object = (value: unknown): value is object => !is.nullOrUndefined(value) && (is.function_(value) || isObject(value));
is.iterable = (value: unknown): value is IterableIterator => !is.nullOrUndefined(value) && is.function_((value as IterableIterator)[Symbol.iterator]);
+
+// eslint-disable-next-line no-use-extend-native/no-use-extend-native
is.asyncIterable = (value: unknown): value is AsyncIterableIterator => !is.nullOrUndefined(value) && is.function_((value as AsyncIterableIterator)[Symbol.asyncIterator]);
+
is.generator = (value: unknown): value is Generator => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
is.nativePromise = (value: unknown): value is Promise =>
@@ -148,7 +151,11 @@ const hasPromiseAPI = (value: unknown): value is Promise =>
is.promise = (value: unknown): value is Promise => is.nativePromise(value) || hasPromiseAPI(value);
is.generatorFunction = isObjectOfType(TypeName.GeneratorFunction);
+
+// eslint-disable-next-line @typescript-eslint/ban-types
is.asyncFunction = isObjectOfType(TypeName.AsyncFunction);
+
+// eslint-disable-next-line no-prototype-builtins, @typescript-eslint/ban-types
is.boundFunction = (value: unknown): value is Function => is.function_(value) && !value.hasOwnProperty('prototype');
is.regExp = isObjectOfType(TypeName.RegExp);
@@ -182,7 +189,7 @@ is.urlString = (value: unknown): value is string => {
}
try {
- new URLGlobal(value); // tslint:disable-line no-unused-expression
+ new URLGlobal(value); // eslint-disable-line no-new
return true;
} catch {
return false;
@@ -215,11 +222,13 @@ is.safeInteger = (value: unknown): value is number => Number.isSafeInteger(value
is.plainObject = (value: unknown): value is {[key: string]: unknown} => {
// From: https://github.com/sindresorhus/is-plain-obj/blob/master/index.js
- let prototype;
+ if (getObjectType(value) !== TypeName.Object) {
+ return false;
+ }
- return getObjectType(value) === TypeName.Object &&
- (prototype = Object.getPrototypeOf(value), prototype === null || // tslint:disable-line:ban-comma-operator
- prototype === Object.getPrototypeOf({}));
+ const prototype = Object.getPrototypeOf(value);
+
+ return prototype === null || prototype === Object.getPrototypeOf({});
};
const typedArrayTypes = new Set([
@@ -250,7 +259,7 @@ export interface ArrayLike {
readonly [index: number]: T;
}
-const isValidLength = (value: unknown) => is.safeInteger(value) && value >= 0;
+const isValidLength = (value: unknown): value is number => is.safeInteger(value) && value >= 0;
is.arrayLike = (value: unknown): value is ArrayLike => !is.nullOrUndefined(value) && !is.function_(value) && isValidLength((value as ArrayLike).length);
is.inRange = (value: number, range: number | number[]): value is number => {
@@ -287,6 +296,7 @@ is.observable = (value: unknown): value is ObservableLike => {
return false;
}
+ // eslint-disable-next-line no-use-extend-native/no-use-extend-native
if ((value as any)[Symbol.observable] && value === (value as any)[Symbol.observable]()) {
return true;
}
@@ -298,13 +308,14 @@ is.observable = (value: unknown): value is ObservableLike => {
return false;
};
+// eslint-disable-next-line @typescript-eslint/ban-types
export type NodeStream = object & {readonly pipe: Function};
is.nodeStream = (value: unknown): value is NodeStream => !is.nullOrUndefined(value) && isObject(value) as unknown && is.function_((value as NodeStream).pipe) && !is.observable(value);
is.infinite = (value: unknown): value is number => value === Infinity || value === -Infinity;
-const isAbsoluteMod2 = (rem: number) => (value: number): value is number => is.integer(value) && Math.abs(value % 2) === rem;
+const isAbsoluteMod2 = (remainder: number) => (value: number): value is number => is.integer(value) && Math.abs(value % 2) === remainder;
is.evenInteger = isAbsoluteMod2(0);
is.oddInteger = isAbsoluteMod2(1);
@@ -316,7 +327,7 @@ is.emptyString = (value: unknown): value is '' => is.string(value) && value.leng
// TODO: Use `not ''` when the `not` operator is available.
is.nonEmptyString = (value: unknown): value is string => is.string(value) && value.length > 0;
-const isWhiteSpaceString = (value: unknown) => is.string(value) && /\S/.test(value) === false;
+const isWhiteSpaceString = (value: unknown): value is string => is.string(value) && /\S/.test(value) === false;
is.emptyStringOrWhitespace = (value: unknown): value is string => is.emptyString(value) || isWhiteSpaceString(value);
is.emptyObject = (value: unknown): value is {[key: string]: never} => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length === 0;
@@ -347,10 +358,8 @@ const predicateOnArray = (method: ArrayMethod, predicate: Predicate, values: unk
return method.call(values, predicate);
};
-// tslint:disable variable-name
is.any = (predicate: Predicate, ...values: unknown[]): boolean => predicateOnArray(Array.prototype.some, predicate, values);
is.all = (predicate: Predicate, ...values: unknown[]): boolean => predicateOnArray(Array.prototype.every, predicate, values);
-// tslint:enable variable-name
// Some few keywords are reserved, but we'll populate them for Node.js users
// See https://github.com/Microsoft/TypeScript/issues/2536
diff --git a/test/test.ts b/test/test.ts
index 4097b4a..d25d28b 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -2,8 +2,8 @@ import fs from 'fs';
import net from 'net';
import Stream from 'stream';
import util from 'util';
-import tempy from 'tempy';
import {URL} from 'url';
+import tempy from 'tempy';
import test, {ExecutionContext} from 'ava';
import {JSDOM} from 'jsdom';
import {Subject, Observable} from 'rxjs';
@@ -88,26 +88,24 @@ const types = new Map([
is: is.array,
fixtures: [
[1, 2],
- new Array(2) // tslint:disable-line:prefer-array-literal
+ new Array(2)
]
}],
['emptyArray', {
is: is.emptyArray,
fixtures: [
[],
- new Array()
+ new Array() // eslint-disable-line @typescript-eslint/no-array-constructor
]
}],
['function', {
is: is.function_,
fixtures: [
- // tslint:disable:no-unused no-empty no-unused-variable only-arrow-functions no-function-expression
- function foo() {},
+ function foo() {}, // eslint-disable-line func-names
function () {},
() => {},
async function () {},
function * (): unknown {}
- // tslint:enable:no-unused no-empty no-unused-variable only-arrow-functions no-function-expression
]
}],
['buffer', {
@@ -153,7 +151,7 @@ const types = new Map([
['promise', {
is: is.promise,
fixtures: [
- {then() {}, catch() {}} // tslint:disable-line:no-empty
+ {then() {}, catch() {}}
]
}],
['generator', {
@@ -175,27 +173,27 @@ const types = new Map([
['asyncFunction', {
is: is.asyncFunction,
fixtures: [
- async function () {}, // tslint:disable-line:no-empty only-arrow-functions no-function-expression
- async () => {} // tslint:disable-line:no-empty
+ async function () {},
+ async () => {}
]
}],
['boundFunction', {
is: is.boundFunction,
fixtures: [
- () => {}, // tslint:disable-line:no-empty
- function () {}.bind(null), // tslint:disable-line:no-empty only-arrow-functions
+ () => {},
+ function () {}.bind(null) // eslint-disable-line no-extra-bind
]
}],
['map', {
is: is.map,
fixtures: [
- new Map([['one', '1']]),
+ new Map([['one', '1']])
]
}],
['emptyMap', {
is: is.emptyMap,
fixtures: [
- new Map(),
+ new Map()
]
}],
['set', {
@@ -207,7 +205,7 @@ const types = new Map([
['emptySet', {
is: is.emptySet,
fixtures: [
- new Set(),
+ new Set()
]
}],
['weakSet', {
@@ -307,7 +305,7 @@ const types = new Map([
fixtures: [
{x: 1},
Object.create(null),
- new Object()
+ new Object() // eslint-disable-line no-new-object
]
}],
['integer', {
@@ -319,8 +317,8 @@ const types = new Map([
['safeInteger', {
is: is.safeInteger,
fixtures: [
- Math.pow(2, 53) - 1,
- -Math.pow(2, 53) + 1
+ (2 ** 53) - 1,
+ -(2 ** 53) + 1
]
}],
['domElement', {
@@ -332,8 +330,8 @@ const types = new Map([
'img',
'canvas',
'script'
- ].map(createDomElement) }
- ],
+ ].map(createDomElement)
+ }],
['non-domElements', {
is: value => !is.domElement(value),
fixtures: [
@@ -350,7 +348,7 @@ const types = new Map([
fixtures: [
new Observable(),
new Subject(),
- new ZenObservable(() => {}) // tslint:disable-line:no-empty
+ new ZenObservable(() => {})
]
}],
['nodeStream', {
@@ -449,7 +447,7 @@ test('is.function', t => {
});
test('is.boundFunction', t => {
- t.false(is.boundFunction(function () {})); // tslint:disable-line:no-empty only-arrow-functions
+ t.false(is.boundFunction(function () {})); // eslint-disable-line prefer-arrow-callback
});
test('is.buffer', t => {
@@ -491,9 +489,11 @@ if (isNode8orHigher) {
testType(t, 'promise', ['nativePromise']);
});
- /*test('is.asyncFunction', t => {
+ /*-
+ test('is.asyncFunction', t => {
testType(t, 'asyncFunction', ['function']);
- });*/
+ });
+ */
}
test('is.generator', t => {
@@ -642,8 +642,8 @@ test('is.integer', t => {
test('is.safeInteger', t => {
testType(t, 'safeInteger', ['number', 'integer']);
- t.false(is.safeInteger(Math.pow(2, 53)));
- t.false(is.safeInteger(-Math.pow(2, 53)));
+ t.false(is.safeInteger(2 ** 53));
+ t.false(is.safeInteger(-(2 ** 53)));
});
test('is.plainObject', t => {
@@ -665,7 +665,7 @@ test('is.iterable', t => {
if (isNode10orHigher) {
test('is.asyncIterable', t => {
t.true(is.asyncIterable({
- [Symbol.asyncIterator]: () => {} // tslint:disable-line:no-empty
+ [Symbol.asyncIterator]: () => {}
}));
t.false(is.asyncIterable(null));
@@ -678,14 +678,15 @@ if (isNode10orHigher) {
}
test('is.class', t => {
- class Foo {} // tslint:disable-line
+ class Foo {} // eslint-disable-line @typescript-eslint/no-extraneous-class
+
const classDeclarations = [
Foo,
- class Bar extends Foo {} // tslint:disable-line
+ class Bar extends Foo {}
];
- for (const x of classDeclarations) {
- t.true(is.class_(x));
+ for (const classDeclaration of classDeclarations) {
+ t.true(is.class_(classDeclaration));
}
});
@@ -714,14 +715,15 @@ test('is.typedArray', t => {
});
test('is.arrayLike', t => {
- (function () { // tslint:disable-line:only-arrow-functions
- t.true(is.arrayLike(arguments));
+ (function () {
+ t.true(is.arrayLike(arguments)); // eslint-disable-line prefer-rest-params
})();
+
t.true(is.arrayLike([]));
t.true(is.arrayLike('unicorn'));
t.false(is.arrayLike({}));
- t.false(is.arrayLike(() => {})); // tslint:disable-line:no-empty
+ t.false(is.arrayLike(() => {}));
t.false(is.arrayLike(new Map()));
});
@@ -800,7 +802,7 @@ test('is.emptyArray', t => {
test('is.nonEmptyArray', t => {
t.true(is.nonEmptyArray([1, 2, 3]));
t.false(is.nonEmptyArray([]));
- t.false(is.nonEmptyArray(new Array()));
+ t.false(is.nonEmptyArray(new Array())); // eslint-disable-line @typescript-eslint/no-array-constructor
});
test('is.emptyString', t => {
@@ -823,7 +825,7 @@ test('is.emptyStringOrWhitespace', t => {
test('is.emptyObject', t => {
t.true(is.emptyObject({}));
- t.true(is.emptyObject(new Object()));
+ t.true(is.emptyObject(new Object())); // eslint-disable-line no-new-object
t.false(is.emptyObject({unicorn: '🦄'}));
});
@@ -832,7 +834,7 @@ test('is.nonEmptyObject', t => {
is.nonEmptyObject(foo);
t.false(is.nonEmptyObject({}));
- t.false(is.nonEmptyObject(new Object()));
+ t.false(is.nonEmptyObject(new Object())); // eslint-disable-line no-new-object
t.true(is.nonEmptyObject({unicorn: '🦄'}));
});
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index 6f6ad0e..0000000
--- a/tslint.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": "tslint-xo",
- "rules": {
- "interface-over-type-literal": false
- }
-}