Skip to content

Latest commit

History

History
70 lines (53 loc) 路 1.83 KB

readme.md

File metadata and controls

70 lines (53 loc) 路 1.83 KB

union

Back to root readme.md

This function can be used when you want an input to be one of a set of types as shown in the example below. This function is a higher order rule as it uses a sub-rules to validate the input, if all of the sub-rules throw an error, then the errors from the sub-rules will be thrown in a rulr.UnionValidationError.

import * as rulr from 'rulr'

const constrainToExample = rulr.object({
	required: {
		example: rulr.union(rulr.number, rulr.string),
	},
})

type Example = rulr.Static<typeof constrainToExample>
// {
//   example: number | string
// }

// Valid
const example1: Example = constrainToExample({
	example: 1,
})

// Valid
const example2: Example = constrainToExample({
	example: '1',
})

// Invalid
const example3: Example = constrainToExample({
	example: true,
})

You may find the rulr.guard function useful to discriminate your union possibilities, especially if you're using union with rulr.object as shown below. It's best to use guards on pre-validated and sanitized data because rulr.guard will ignore the sanitization provided by rules such as rulr.object which removes properties that were not specified in the provided schema.

import * as rulr from 'rulr'

const stringObjectSymbol = Symbol()

const stringObject = rulr.object({
	required: {
		type: rulr.constant(stringObjectSymbol, 'text'),
		text: rulr.string,
	},
})

const isStringObject = rulr.guard(stringObject)

const numberObjectSymbol = Symbol()

const numberObject = rulr.object({
	required: {
		type: rulr.constant(numberObjectSymbol, 'num'),
		num: rulr.number,
	},
})

const constrainToExample = rulr.union(stringObject, numberObject)

const example = constrainToExample({ type: 'text', text: 'hello' })
if (isStringObject(example)) {
	console.log(example.text)
} else {
	console.log(example.num)
}