Implement named exports (#191)
This commit is contained in:
parent
bd5dfda993
commit
5044c91273
4 changed files with 1282 additions and 409 deletions
48
readme.md
48
readme.md
|
|
@ -54,6 +54,18 @@ assert.string(foo);
|
||||||
// `foo` is now typed as a `string`.
|
// `foo` is now typed as a `string`.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Named exports
|
||||||
|
|
||||||
|
Named exports allow tooling to perform tree-shaking, potentially reducing bundle size by including only code from the methods that are used.
|
||||||
|
|
||||||
|
Every method listed below is available as a named export. Each method is prefixed by either `is` or `assert` depending on usage.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import {assertNull, isUndefined} from '@sindresorhus/is';
|
||||||
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### is(value)
|
### is(value)
|
||||||
|
|
@ -72,19 +84,23 @@ Example:
|
||||||
- `'Function'`
|
- `'Function'`
|
||||||
- `'Object'`
|
- `'Object'`
|
||||||
|
|
||||||
|
This method is also exported as `detect`. You can import it like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import {detect} from '@sindresorhus/is';
|
||||||
|
```
|
||||||
|
|
||||||
Note: It will throw an error if you try to feed it object-wrapped primitives, as that's a bad practice. For example `new String('foo')`.
|
Note: It will throw an error if you try to feed it object-wrapped primitives, as that's a bad practice. For example `new String('foo')`.
|
||||||
|
|
||||||
### is.{method}
|
### is.{method}
|
||||||
|
|
||||||
All the below methods accept a value and returns a boolean for whether the value is of the desired type.
|
All the below methods accept a value and return a boolean for whether the value is of the desired type.
|
||||||
|
|
||||||
#### Primitives
|
#### Primitives
|
||||||
|
|
||||||
##### .undefined(value)
|
##### .undefined(value)
|
||||||
##### .null(value)
|
##### .null(value)
|
||||||
|
|
||||||
**Note:** TypeScript users must use `.null_()` because of a TypeScript naming limitation.
|
|
||||||
|
|
||||||
##### .string(value)
|
##### .string(value)
|
||||||
##### .number(value)
|
##### .number(value)
|
||||||
|
|
||||||
|
|
@ -107,8 +123,6 @@ is.array(value, is.number); // Validate `value` is an array and all of its items
|
||||||
|
|
||||||
##### .function(value)
|
##### .function(value)
|
||||||
|
|
||||||
**Note:** TypeScript users must use `.function_()` because of a TypeScript naming limitation.
|
|
||||||
|
|
||||||
##### .buffer(value)
|
##### .buffer(value)
|
||||||
##### .blob(value)
|
##### .blob(value)
|
||||||
##### .object(value)
|
##### .object(value)
|
||||||
|
|
@ -373,7 +387,15 @@ Returns `true` if `value` is one of: `false`, `0`, `''`, `null`, `undefined`, `N
|
||||||
##### .nullOrUndefined(value)
|
##### .nullOrUndefined(value)
|
||||||
##### .primitive(value)
|
##### .primitive(value)
|
||||||
|
|
||||||
JavaScript primitives are as follows: `null`, `undefined`, `string`, `number`, `boolean`, `symbol`.
|
JavaScript primitives are as follows:
|
||||||
|
|
||||||
|
- `null`
|
||||||
|
- `undefined`
|
||||||
|
- `string`
|
||||||
|
- `number`
|
||||||
|
- `boolean`
|
||||||
|
- `symbol`
|
||||||
|
- `bigint`
|
||||||
|
|
||||||
##### .integer(value)
|
##### .integer(value)
|
||||||
|
|
||||||
|
|
@ -391,8 +413,6 @@ An object is plain if it's created by either `{}`, `new Object()`, or `Object.cr
|
||||||
|
|
||||||
Returns `true` for instances created by a class.
|
Returns `true` for instances created by a class.
|
||||||
|
|
||||||
**Note:** TypeScript users must use `.class_()` because of a TypeScript naming limitation.
|
|
||||||
|
|
||||||
##### .typedArray(value)
|
##### .typedArray(value)
|
||||||
|
|
||||||
##### .arrayLike(value)
|
##### .arrayLike(value)
|
||||||
|
|
@ -458,7 +478,7 @@ is.inRange(3, 10);
|
||||||
|
|
||||||
##### .domElement(value)
|
##### .domElement(value)
|
||||||
|
|
||||||
Returns `true` if `value` is a DOM Element.
|
Returns `true` if `value` is an [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement).
|
||||||
|
|
||||||
##### .nodeStream(value)
|
##### .nodeStream(value)
|
||||||
|
|
||||||
|
|
@ -554,6 +574,16 @@ is.all(is.string, '🦄', [], 'unicorns');
|
||||||
//=> false
|
//=> false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### .validLength(value)
|
||||||
|
|
||||||
|
Returns `true` if the value is a safe integer that is greater than or equal to zero.
|
||||||
|
|
||||||
|
This can be useful to confirm that a value is a valid count of something, ie. 0 or more.
|
||||||
|
|
||||||
|
##### .whitespaceString(value)
|
||||||
|
|
||||||
|
Returns `true` if the value is a string with only whitespace characters.
|
||||||
|
|
||||||
## Type guards
|
## Type guards
|
||||||
|
|
||||||
When using `is` together with TypeScript, [type guards](http://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types) are being used extensively to infer the correct type inside if-else statements.
|
When using `is` together with TypeScript, [type guards](http://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types) are being used extensively to infer the correct type inside if-else statements.
|
||||||
|
|
|
||||||
1582
source/index.ts
1582
source/index.ts
File diff suppressed because it is too large
Load diff
|
|
@ -62,3 +62,14 @@ export type WeakRef<T extends object> = { // eslint-disable-line @typescript-esl
|
||||||
readonly [Symbol.toStringTag]: 'WeakRef';
|
readonly [Symbol.toStringTag]: 'WeakRef';
|
||||||
deref(): T | undefined;
|
deref(): T | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ArrayLike<T> = {
|
||||||
|
readonly [index: number]: T;
|
||||||
|
readonly length: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NodeStream = {
|
||||||
|
pipe<T extends NodeJS.WritableStream>(destination: T, options?: {end?: boolean}): T;
|
||||||
|
} & NodeJS.EventEmitter;
|
||||||
|
|
||||||
|
export type Predicate = (value: unknown) => boolean;
|
||||||
|
|
|
||||||
50
test/test.ts
50
test/test.ts
|
|
@ -61,7 +61,7 @@ const types = new Map<string, Test>([
|
||||||
typename: 'undefined',
|
typename: 'undefined',
|
||||||
}],
|
}],
|
||||||
['null', {
|
['null', {
|
||||||
is: is.null_,
|
is: is.null,
|
||||||
assert: assert.null_,
|
assert: assert.null_,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
null,
|
null,
|
||||||
|
|
@ -161,7 +161,7 @@ const types = new Map<string, Test>([
|
||||||
typeDescription: 'empty array',
|
typeDescription: 'empty array',
|
||||||
}],
|
}],
|
||||||
['function', {
|
['function', {
|
||||||
is: is.function_,
|
is: is.function,
|
||||||
assert: assert.function_,
|
assert: assert.function_,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
function foo() {}, // eslint-disable-line func-names
|
function foo() {}, // eslint-disable-line func-names
|
||||||
|
|
@ -838,7 +838,7 @@ test('is.asyncFunction', t => {
|
||||||
|
|
||||||
const fixture = async () => {};
|
const fixture = async () => {};
|
||||||
if (is.asyncFunction(fixture)) {
|
if (is.asyncFunction(fixture)) {
|
||||||
t.true(is.function_(fixture().then));
|
t.true(is.function(fixture().then));
|
||||||
|
|
||||||
t.notThrows(() => {
|
t.notThrows(() => {
|
||||||
assert.function_(fixture().then);
|
assert.function_(fixture().then);
|
||||||
|
|
@ -857,7 +857,7 @@ test('is.asyncGenerator', t => {
|
||||||
yield 4;
|
yield 4;
|
||||||
})();
|
})();
|
||||||
if (is.asyncGenerator(fixture)) {
|
if (is.asyncGenerator(fixture)) {
|
||||||
t.true(is.function_(fixture.next));
|
t.true(is.function(fixture.next));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -873,7 +873,7 @@ test('is.asyncGeneratorFunction', t => {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is.asyncGeneratorFunction(fixture)) {
|
if (is.asyncGeneratorFunction(fixture)) {
|
||||||
t.true(is.function_(fixture().next));
|
t.true(is.function(fixture().next));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1365,7 +1365,7 @@ test('is.class', t => {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const classDeclaration of classDeclarations) {
|
for (const classDeclaration of classDeclarations) {
|
||||||
t.true(is.class_(classDeclaration));
|
t.true(is.class(classDeclaration));
|
||||||
|
|
||||||
t.notThrows(() => {
|
t.notThrows(() => {
|
||||||
assert.class_(classDeclaration);
|
assert.class_(classDeclaration);
|
||||||
|
|
@ -1456,7 +1456,7 @@ test('is.tupleLike', t => {
|
||||||
t.false(is.tupleLike('unicorn', [is.string]));
|
t.false(is.tupleLike('unicorn', [is.string]));
|
||||||
|
|
||||||
t.false(is.tupleLike({}, []));
|
t.false(is.tupleLike({}, []));
|
||||||
t.false(is.tupleLike(() => {}, [is.function_]));
|
t.false(is.tupleLike(() => {}, [is.function]));
|
||||||
t.false(is.tupleLike(new Map(), [is.map]));
|
t.false(is.tupleLike(new Map(), [is.map]));
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
|
@ -1476,7 +1476,7 @@ test('is.tupleLike', t => {
|
||||||
assert.tupleLike({}, [is.object]);
|
assert.tupleLike({}, [is.object]);
|
||||||
});
|
});
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
assert.tupleLike(() => {}, [is.function_]);
|
assert.tupleLike(() => {}, [is.function]);
|
||||||
});
|
});
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
assert.tupleLike(new Map(), [is.map]);
|
assert.tupleLike(new Map(), [is.map]);
|
||||||
|
|
@ -1496,7 +1496,7 @@ test('is.tupleLike', t => {
|
||||||
{
|
{
|
||||||
const tuple = [{isTest: true}, '1', true, null];
|
const tuple = [{isTest: true}, '1', true, null];
|
||||||
|
|
||||||
if (is.tupleLike(tuple, [is.nonEmptyObject, is.string, is.boolean, is.null_])) {
|
if (is.tupleLike(tuple, [is.nonEmptyObject, is.string, is.boolean, is.null])) {
|
||||||
const value = tuple[0];
|
const value = tuple[0];
|
||||||
expectTypeOf(value).toEqualTypeOf<Record<string | number | symbol, unknown>>();
|
expectTypeOf(value).toEqualTypeOf<Record<string | number | symbol, unknown>>();
|
||||||
}
|
}
|
||||||
|
|
@ -1505,7 +1505,7 @@ test('is.tupleLike', t => {
|
||||||
{
|
{
|
||||||
const tuple = [1, '1', true, null, undefined];
|
const tuple = [1, '1', true, null, undefined];
|
||||||
|
|
||||||
if (is.tupleLike(tuple, [is.number, is.string, is.boolean, is.undefined, is.null_])) {
|
if (is.tupleLike(tuple, [is.number, is.string, is.boolean, is.undefined, is.null])) {
|
||||||
const numericValue = tuple[0];
|
const numericValue = tuple[0];
|
||||||
const stringValue = tuple[1];
|
const stringValue = tuple[1];
|
||||||
const booleanValue = tuple[2];
|
const booleanValue = tuple[2];
|
||||||
|
|
@ -1540,14 +1540,17 @@ test('is.inRange', t => {
|
||||||
t.false(is.inRange(-3, -2));
|
t.false(is.inRange(-3, -2));
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
is.inRange(0, []);
|
is.inRange(0, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
is.inRange(0, [5]);
|
is.inRange(0, [5]);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
is.inRange(0, [1, 2, 3]);
|
is.inRange(0, [1, 2, 3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1604,14 +1607,17 @@ test('is.inRange', t => {
|
||||||
});
|
});
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
assert.inRange(0, []);
|
assert.inRange(0, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
assert.inRange(0, [5]);
|
assert.inRange(0, [5]);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
|
// @ts-expect-error invalid argument
|
||||||
assert.inRange(0, [1, 2, 3]);
|
assert.inRange(0, [1, 2, 3]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -2072,6 +2078,30 @@ test('is.urlSearchParams', t => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('is.validLength', t => {
|
||||||
|
t.true(is.validLength(1));
|
||||||
|
t.true(is.validLength(0));
|
||||||
|
t.false(is.validLength(-1));
|
||||||
|
t.false(is.validLength(0.1));
|
||||||
|
t.notThrows(() => {
|
||||||
|
assert.validLength(1);
|
||||||
|
});
|
||||||
|
t.throws(() => {
|
||||||
|
assert.validLength(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('is.whitespaceString', t => {
|
||||||
|
t.true(is.whitespaceString(' '));
|
||||||
|
t.true(is.whitespaceString(' '));
|
||||||
|
t.true(is.whitespaceString(' '));
|
||||||
|
t.true(is.whitespaceString('\u3000'));
|
||||||
|
t.true(is.whitespaceString(' '));
|
||||||
|
t.false(is.whitespaceString(''));
|
||||||
|
t.false(is.whitespaceString('-'));
|
||||||
|
t.false(is.whitespaceString(' hi '));
|
||||||
|
});
|
||||||
|
|
||||||
test('assert', t => {
|
test('assert', t => {
|
||||||
// Contrived test showing that TypeScript acknowledges the type assertion in `assert.number()`.
|
// Contrived test showing that TypeScript acknowledges the type assertion in `assert.number()`.
|
||||||
// Real--world usage includes asserting user input, but here we use a random number/string generator.
|
// Real--world usage includes asserting user input, but here we use a random number/string generator.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue