superstruct
superstruct copied to clipboard
combine `type` and `object` structs?
Curious to hear other perspectives on this.
Right now the only difference between type
and object
struct is the "looseness" of the properties. type
doesn't care about unknown properties, whereas object
is "strict" and throws when unknown properties are received.
I was thinking it might make sense to just make type
a subset of object
that is accessed via a { loose: true }
option:
const Nameable = object({
first_name: string(),
last_name: string(),
}, {
loose: true
})
Might be easier to find/understand for new users.
Could also allow layering in the masked
utility as { mask: true }
as well, since it only applies to objects.
When doing either of these we'd ensure that object structs can be passed as schemes to new object structs, so that you can immutably change the settings, for example:
const User = object({
id: number(),
name: string(),
})
const PermissiveUser = object(User, { loose: true, mask: true })
I use superstruct to validate configuration file. Sometimes someone might have a typo on the key field. I want the users to notice that mistake but I don't want to throw error and stop execution. So something like onExtraField
will be useful.
const User = object({
id: number(),
name: string(),
nickname: optional(string())
}, {
// `onExtraField` is only valid when loose is `true`, so `onExtraField` is under `loose`
loose: {
onExtraField: fieldName => {
console.log(`Unknown field '${fieldName}'`)
}
}
})
// Console output `Unknown field 'nicknmae'` without throwing error
User.assert({
id: 1,
name: 'Tony Stark',
// Typo in the field name here
nicknmae: 'Iron Man'
})