Skip to content

Commit

Permalink
Add Infer type utility (#221)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
  • Loading branch information
jorisre and sindresorhus authored Sep 22, 2021
1 parent 3728d91 commit 7602fb0
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
14 changes: 14 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,20 @@ ow(

This can be useful for creating your own reusable validators which can be extracted to a separate npm package.

### TypeScript

Ow includes a type utility that lets you to extract a TypeScript type from the given predicate.

```ts
import ow, {Infer} from 'ow';

const userPredicate = ow.object.exactShape({
name: ow.string
});

type User = Infer<typeof userPredicate>;
```

## Maintainers

- [Sindre Sorhus](https://github.com/sindresorhus)
Expand Down
16 changes: 16 additions & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ import test from './test';
*/
export type Main = <T>(value: T, label: string | Function, predicate: BasePredicate<T>, idLabel?: boolean) => void;

/**
Retrieve the type from the given predicate.
@example
```
import ow, {Infer} from 'ow';
const userPredicate = ow.object.exactShape({
name: ow.string
});
type User = Infer<typeof userPredicate>;
```
*/
export type Infer<P> = P extends BasePredicate<infer T> ? T : never;

// Extends is only necessary for the generated documentation to be cleaner. The loaders below infer the correct type.
export interface Ow extends Modifiers, Predicates {
/**
Expand Down
88 changes: 87 additions & 1 deletion test/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava';
import {ExpectTypeOf, expectTypeOf} from 'expect-type';
import {TypedArray} from 'type-fest';
import ow, {BasePredicate} from '../source';
import ow, {BasePredicate, Infer} from '../source';

test('type-level tests', t => {
t.is(typeof typeTests, 'function');
Expand Down Expand Up @@ -143,6 +143,92 @@ function typeTests(value: unknown): Array<(() => void)> {
};

return tests;
},

(): void => {
const schema = ow.object.exactShape({
undefined: ow.undefined,
null: ow.null,
nullOrUndefined: ow.nullOrUndefined,
optionalString: ow.optional.string,
number: ow.number,
boolean: ow.boolean,
symbol: ow.symbol,
array: ow.array,
function: ow.function,
buffer: ow.buffer,
object: ow.object,
regExp: ow.regExp,
date: ow.date,
error: ow.error,
promise: ow.promise,
map: ow.map,
set: ow.set,
weakMap: ow.weakMap,
weakSet: ow.weakSet,
int8Array: ow.int8Array,
uint8Array: ow.uint8Array,
uint8ClampedArray: ow.uint8ClampedArray,
int16Array: ow.int16Array,
uint16Array: ow.uint16Array,
int32Array: ow.int32Array,
uint32Array: ow.uint32Array,
float32Array: ow.float32Array,
float64Array: ow.float64Array,
arrayBuffer: ow.arrayBuffer,
dataView: ow.dataView,
sharedArrayBuffer: ow.sharedArrayBuffer,
nan: ow.nan,
iterable: ow.iterable,
typedArray: ow.typedArray,
nested: ow.object.exactShape({
nested: ow.array.ofType(
ow.object.exactShape({
nested: ow.number
})
)
})
});

expectTypeOf<Infer<typeof schema>>().toEqualTypeOf<{
undefined: undefined;
null: null;
nullOrUndefined: null | undefined;
optionalString: string | undefined;
number: number;
boolean: boolean;
symbol: symbol;
array: unknown[];
function: Function;
buffer: Buffer;
object: object;
regExp: RegExp;
date: Date;
error: Error;
promise: Promise<unknown>;
map: Map<unknown, unknown>;
set: Set<any>;
weakMap: WeakMap<object, unknown>;
weakSet: WeakSet<object>;
int8Array: Int8Array;
uint8Array: Uint8Array;
uint8ClampedArray: Uint8ClampedArray;
int16Array: Int16Array;
uint16Array: Uint16Array;
int32Array: Int32Array;
uint32Array: Uint32Array;
float32Array: Float32Array;
float64Array: Float64Array;
arrayBuffer: ArrayBuffer;
dataView: DataView;
sharedArrayBuffer: SharedArrayBuffer;
nan: number;
iterable: Iterable<unknown>;
typedArray: TypedArray;
nested: {
nested: Array<{nested: number}>;
};
}>();
}
];
}

0 comments on commit 7602fb0

Please sign in to comment.