Created
March 15, 2020 04:55
-
-
Save itsMapleLeaf/0aaee24dd8cd440962246fb85457aeb9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type Validator<T = unknown> = { | |
| parse: (value: unknown) => T | |
| is: (value: unknown) => value is T | |
| } | |
| type ValidatorType<V> = V extends Validator<infer T> ? T : never | |
| type ValueOf<T> = T extends readonly (infer V)[] ? V : T[keyof T] | |
| const raise = (error: string): never => { | |
| throw new Error(error) | |
| } | |
| const createValidator = <T,>( | |
| isValid: (value: unknown) => value is T, | |
| errorMessage: string, | |
| ): Validator<T> => ({ | |
| is: isValid, | |
| parse: arg => (isValid(arg) ? arg : raise(errorMessage)), | |
| }) | |
| export const string = createValidator( | |
| (value): value is string => typeof value === 'string', | |
| 'value is not a string', | |
| ) | |
| export const number = createValidator( | |
| (value): value is number => typeof value === 'number', | |
| 'value is not a number', | |
| ) | |
| export const boolean = createValidator( | |
| (value): value is boolean => typeof value === 'boolean', | |
| 'value is not a boolean', | |
| ) | |
| export const union = <T extends Validator[]>(...memberTypes: T) => | |
| createValidator( | |
| (value): value is ValidatorType<ValueOf<T>> => memberTypes.some(type => type.is(value)), | |
| 'union check failed', | |
| ) | |
| export const array = <T,>(itemType: Validator<T>) => | |
| createValidator( | |
| (value): value is T[] => | |
| Array.isArray(value) && value.every(item => itemType.is(item)), | |
| 'expected array, received otherwise', | |
| ) | |
| export const literal = <T,>(value: T) => | |
| createValidator((arg): arg is T => arg === value, 'literal check failed') | |
| declare const unsafeValue: unknown | |
| const test = union(string, array(number)) | |
| const value = test.parse(unsafeValue) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment