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) // => ParseError
Parse 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.