Open mrdziuban opened 2 years ago
If we look at the code for NumberFromString^1 we see the type-guard is implemented to check that the input value is a number. In general, for the AfromB
codecs, the type guard checks for type A, which matches the decoded type A. In other words, type guards on these type-converting codecs are seemingly intended to be used on decoded values.
It seems like your first attempt in the snippet above would work, but Records are where things get tricky. First, note that t.record
really only shines with the specific codec t.string
in the domain (keys); even branded strings produce unacceptably-poor type inferencing (widens to any
). This is probably why the domain is fixed as string
(non-parameterized) in io-ts v3.
Technically in bare TypeScript Records accept a domain of string | number | Symbol
but even this is a bit of a stretch of the truth -- in the node repl we can see
$ node
Welcome to Node.js v16.13.1.
Type ".help" for more information.
> const a = { 4: 'more' }
undefined
> a
{ '4': 'more' }
> a['4']
'more'
that number keys are coerced into strings. This is probably why your first attempt failed, because the number you started with did not exist by the time your codec's type-guard ran.
If you need arbitrary types for your domain, consider using an es6 Map.
When using
NumberFromString
along witht.record
, theis
method of the resulting codec always returnsfalse
, e.g.:Is there any way I could get this working without defining a custom codec? Thanks in advance!
P.S. I wasn't sure if I should open this issue here or in the base
io-ts
repository so let me know if you'd like me to re-open it there.