Skip to content

Instantly share code, notes, and snippets.

@yuriuliam
Created December 7, 2023 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuriuliam/27a052d37596ef5eef0e6778f05a4c17 to your computer and use it in GitHub Desktop.
Save yuriuliam/27a052d37596ef5eef0e6778f05a4c17 to your computer and use it in GitHub Desktop.
create a simple, message-based abstract validator
type ValidateRuleFn<T> = (data: T) => string[] | null
type Priority = 'WARN' | 'ERROR'
type RuleTuple<T> = [priority: Priority, validateRule: ValidateRuleFn<T>]
type ValidationResult = { errors: string[], warnings: string[] }
const RESULT_KEYS: Record<Priority, string> = {
ERROR: 'errors',
WARN: 'warnings'
}
const VALID_PRIORITIES: Priority[] = ['ERROR', 'WARN']
const createValidator = <T>(...entries: Array<RuleTuple<T>>) => {
if (!structuredClone) {
throw new ReferenceError('structuredClone should be supported!')
}
if (!entries.every(([priority]) => VALID_PRIORITIES.includes(priority))) {
throw new TypeError('there are invalid priorities')
}
return (data: T) => entries.reduce<ValidationResult>(
(acc, [priority, validateRule]) => {
const result = validateRule(structuredClone(data))
if (!result) return acc
const resultKey = Reflect.get(RESULT_KEYS, priority)
return {
...acc,
[resultKey]: [...acc[resultKey], result]
}
},
{ errors: [], warnings: [] }
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment