oneOf()
function oneOf<T>(...parsers): Parser<T[number]>Executes parsers in order and returns the first successful parsing attempt, or a failure if all fail. Use it to parse unions, to parse data that comes in different shape, and to provide fallbacks for failed parsing attempts.
See
withDefault for a shorthand for fallback with a static value.
Type Parameters
| Type Parameter |
|---|
T extends readonly unknown[] |
Parameters
| Parameter | Type | Description |
|---|---|---|
...parsers | { [K in string | number | symbol]: Parser<T[K<K>]> } | A list of parsers to be called in order. |
Returns
Parser<T[number]>
A parser function that will call the parsers in parsers in order and return the result of the first successful parsing attempt, or a failure if all parsing attempts fail.
Examples
Parse unions:
const parseNumberOrString = oneOf(parseNumber, parseString)
parseNumberOrString(0) // => ParseSuccess<number | string>
parseNumberOrString('abc') // => ParseSuccess<number | string>
parseNumberOrString(null) // => ParseErrorParse discriminated unions:
const parseResult = oneOf(
object({
tag: equals('success')
value: parseString
}),
object({
tag: equals('error')
}),
)Provide fallbacks for failed parsing attempts; for example, parse a number from data that is either a number or a stringified number:
const parseStrOrNum = fallback([parseNumber, parseNumberFromString])
parseStrOrNum(2) // -> { tag: 'success', value: 2 }
parseStrOrNum('2') // -> { tag: 'success', value: 2 }(Do not encode data like this when there's a choice; but sometimes, existing data comes in weird shapes and forms.)
Provide a static default value when parsing fails:
const parseName = oneOf([
parseString,
() => success('Anonymous')
])You can also use withDefault for this use case.
When explicitly annotating oneOf, provide a tuple as type argument:
type Success = {
tag: 'success'
value: string
}
type Failure = {
tag: 'failure'
}
type Result = Success | Failure
const parseLogLevel = equals<[Success, Failure]>(
object({
tag: equals('success')
value: parseString
}),
object({
tag: equals('error')
}),
)Due to a limitation of TypeScript, it is not possible to write oneOf<string | number>(). Therefore, it is generally recommended to omit the type arguments for oneOf and let TypeScript infer them.
