superstruct
superstruct copied to clipboard
Coercing a refined struct doesn't trigger refinement
Consider this example, where we have a refiner and a coercer:
import { coerce, create, number, refine, string } from 'superstruct'
const BigNumber = refine(number(), 'Big Number', (value) => {
return value > 100 ? true : "Number isn't big enough!"
})
const StringBigNumber = coerce(string(), BigNumber, (value) => {
return `${value}`
})
Based on the documentation on coercing data:
The second argument to coerce is a struct narrowing the types of input values you want to try coercion. In the example above, the coercion function will only ever be called when the input is a string—booleans would ignore coercion and fail normally.
Expected
This implies to me that the coercer will only run if the number is a valid BigNumber
. If it fails, then I should expect the error message to contain the message from the refiner.
// ... above code
create(30, StringBigNumber) // Fails, "Number isn't big enough!"
create('hello', StringBigNumber) // Fails, "Expected a number, but received: "hello""
Actual
The coercer skips the refiner entirely, ignoring its validation and just checking that it
// ... above code
create(30, StringBigNumber) // Fails, "Expected a string, but received: 30"
create('Hello!', StringBigNumber) // Pass, not even a number
Is this intentional? To me the documentation says it should first pass the second struct, and then do coercion, then pass the first struct.