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`.
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
### is(value)
|
||||
|
|
@ -72,19 +84,23 @@ Example:
|
|||
- `'Function'`
|
||||
- `'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')`.
|
||||
|
||||
### 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
|
||||
|
||||
##### .undefined(value)
|
||||
##### .null(value)
|
||||
|
||||
**Note:** TypeScript users must use `.null_()` because of a TypeScript naming limitation.
|
||||
|
||||
##### .string(value)
|
||||
##### .number(value)
|
||||
|
||||
|
|
@ -107,8 +123,6 @@ is.array(value, is.number); // Validate `value` is an array and all of its items
|
|||
|
||||
##### .function(value)
|
||||
|
||||
**Note:** TypeScript users must use `.function_()` because of a TypeScript naming limitation.
|
||||
|
||||
##### .buffer(value)
|
||||
##### .blob(value)
|
||||
##### .object(value)
|
||||
|
|
@ -373,7 +387,15 @@ Returns `true` if `value` is one of: `false`, `0`, `''`, `null`, `undefined`, `N
|
|||
##### .nullOrUndefined(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)
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
**Note:** TypeScript users must use `.class_()` because of a TypeScript naming limitation.
|
||||
|
||||
##### .typedArray(value)
|
||||
|
||||
##### .arrayLike(value)
|
||||
|
|
@ -458,7 +478,7 @@ is.inRange(3, 10);
|
|||
|
||||
##### .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)
|
||||
|
||||
|
|
@ -554,6 +574,16 @@ is.all(is.string, '🦄', [], 'unicorns');
|
|||
//=> 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
|
||||
|
||||
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';
|
||||
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',
|
||||
}],
|
||||
['null', {
|
||||
is: is.null_,
|
||||
is: is.null,
|
||||
assert: assert.null_,
|
||||
fixtures: [
|
||||
null,
|
||||
|
|
@ -161,7 +161,7 @@ const types = new Map<string, Test>([
|
|||
typeDescription: 'empty array',
|
||||
}],
|
||||
['function', {
|
||||
is: is.function_,
|
||||
is: is.function,
|
||||
assert: assert.function_,
|
||||
fixtures: [
|
||||
function foo() {}, // eslint-disable-line func-names
|
||||
|
|
@ -838,7 +838,7 @@ test('is.asyncFunction', t => {
|
|||
|
||||
const fixture = async () => {};
|
||||
if (is.asyncFunction(fixture)) {
|
||||
t.true(is.function_(fixture().then));
|
||||
t.true(is.function(fixture().then));
|
||||
|
||||
t.notThrows(() => {
|
||||
assert.function_(fixture().then);
|
||||
|
|
@ -857,7 +857,7 @@ test('is.asyncGenerator', t => {
|
|||
yield 4;
|
||||
})();
|
||||
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)) {
|
||||
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) {
|
||||
t.true(is.class_(classDeclaration));
|
||||
t.true(is.class(classDeclaration));
|
||||
|
||||
t.notThrows(() => {
|
||||
assert.class_(classDeclaration);
|
||||
|
|
@ -1456,7 +1456,7 @@ test('is.tupleLike', t => {
|
|||
t.false(is.tupleLike('unicorn', [is.string]));
|
||||
|
||||
t.false(is.tupleLike({}, []));
|
||||
t.false(is.tupleLike(() => {}, [is.function_]));
|
||||
t.false(is.tupleLike(() => {}, [is.function]));
|
||||
t.false(is.tupleLike(new Map(), [is.map]));
|
||||
|
||||
(function () {
|
||||
|
|
@ -1476,7 +1476,7 @@ test('is.tupleLike', t => {
|
|||
assert.tupleLike({}, [is.object]);
|
||||
});
|
||||
t.throws(() => {
|
||||
assert.tupleLike(() => {}, [is.function_]);
|
||||
assert.tupleLike(() => {}, [is.function]);
|
||||
});
|
||||
t.throws(() => {
|
||||
assert.tupleLike(new Map(), [is.map]);
|
||||
|
|
@ -1496,7 +1496,7 @@ test('is.tupleLike', t => {
|
|||
{
|
||||
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];
|
||||
expectTypeOf(value).toEqualTypeOf<Record<string | number | symbol, unknown>>();
|
||||
}
|
||||
|
|
@ -1505,7 +1505,7 @@ test('is.tupleLike', t => {
|
|||
{
|
||||
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 stringValue = tuple[1];
|
||||
const booleanValue = tuple[2];
|
||||
|
|
@ -1540,14 +1540,17 @@ test('is.inRange', t => {
|
|||
t.false(is.inRange(-3, -2));
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
is.inRange(0, []);
|
||||
});
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
is.inRange(0, [5]);
|
||||
});
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
is.inRange(0, [1, 2, 3]);
|
||||
});
|
||||
|
||||
|
|
@ -1604,14 +1607,17 @@ test('is.inRange', t => {
|
|||
});
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
assert.inRange(0, []);
|
||||
});
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
assert.inRange(0, [5]);
|
||||
});
|
||||
|
||||
t.throws(() => {
|
||||
// @ts-expect-error invalid argument
|
||||
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 => {
|
||||
// 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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue