Skip to content

Commit

Permalink
Merge pull request #4 from hughrawlinson/main
Browse files Browse the repository at this point in the history
Add 'every' type predicate
  • Loading branch information
nshen authored Jun 8, 2022
2 parents 8138167 + 0ac410d commit 78d9c9b
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 3 deletions.
61 changes: 58 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ npm i narrowing # yarn add narrowing
let a: unknown;

if (isXXX(a)) {
// TypeScritp know your type here!
// TypeScript know your type here!
}
```

Expand All @@ -40,7 +40,7 @@ Basic:

Advanced:

These functions help you make advanced type gurads.
These functions help you make advanced type guards.

- [has](#has)
- [kind](#kind)
Expand Down Expand Up @@ -87,7 +87,7 @@ function testFunc(a: string, b: number): boolean {
}

if (isFunction<typeof testFunc>(a)) {
a('11', 1); // no eror
a('11', 1); // no error
}

if (isInstance(a, Date)) {
Expand Down Expand Up @@ -234,6 +234,60 @@ if (isSuccess(message)) {
}
```

schema supports a type argument for associating a schema with an existing type

```ts
interface TestInterface {
id: number;
name: string;
}

const isTestInterface = schema<TestInterface>({
id: isNumber,
name: isString
});

if (isTestInterface(message)) {
// let message: TestInterface
message;
}
```

````
### `every()
Runtime array type validation. Checks each element of an array.
```ts
let arr: unknown[] = [1, 2, 3];
if (every(isNumber)(arr)) {
let typeCheck: number[] = arr;
}
````

Works with any narrowing validator, including schemas.

```ts
interface TestInterface {
id: number;
name: string;
}

const isTestInterface = schema<TestInterface>({
id: isNumber,
name: isString
});

let arr: unknown[] = [{ id: 1, name: 'aaa' }];

if (every(isTestInterface)(arr)) {
let typeCheck: TestInterface[] = arr;
}
```

```
## Version
- 1.1.0
Expand All @@ -247,3 +301,4 @@ if (isSuccess(message)) {
- 1.4.0
- replace ~~`isValidObject()`~~ with `schema()`
- add `literal()`
```
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,12 @@ export function schema<T>(schema: SchemaType<T>): Predicate<T> {
return false;
};
}

export function every<T>(predicate: Predicate<T>): Predicate<T[]> {
return function (value: unknown): value is T[] {
if (Array.isArray(value)) {
return value.every(predicate);
}
return false;
};
}
82 changes: 82 additions & 0 deletions test/every.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { schema, literal, every, isString, isNumber } from '../src/index';

test('fails when array contains elements of an unassignable type', () => {
expect(every(isString)([1, 2, 3])).toBe(false);
expect(every(isNumber)([1, '2', 3])).toBe(false);
});

test('passes when array contains correct type', () => {
expect(every(isNumber)([1, 2, 3])).toBe(true);
expect(every(isString)(['1', '2', '3'])).toBe(true);
});

test('passes when array is empty', () => {
expect(every(isString)([])).toBe(true);
expect(every(isNumber)([])).toBe(true);
});

interface TestInterface {
kind: 'test';
value: {
nestedString: string;
nestedNumber: number;
};
}

const isTestInterface = schema<TestInterface>({
kind: literal('test'),
value: schema<TestInterface['value']>({
nestedString: isString,
nestedNumber: isNumber
})
});

test('passes when array contains valid objects', () => {
expect(
every<TestInterface>(isTestInterface)([
{
kind: 'test',
value: {
nestedString: 'string',
nestedNumber: 1
}
}
])
).toBe(true);
});

test('fails when array contains invalid objects', () => {
expect(
every<TestInterface>(isTestInterface)([
{
kind: 'test',
value: {
nested_string: 'string'
}
}
])
).toBe(false);
});

every<string>(isString);

let arr: unknown[] = [1, 2, 3];
if (every(isNumber)(arr)) {
let typeCheck: number[] = arr;
}

interface TestInterfaceT {
id: number;
name: string;
}

const isTestInterfaceT = schema<TestInterfaceT>({
id: isNumber,
name: isString
});

let arr2: unknown[] = [{ id: 1, name: 'aaa' }];

if (every(isTestInterfaceT)(arr2)) {
let typeCheck: TestInterfaceT[] = arr2;
}

0 comments on commit 78d9c9b

Please # to comment.