hoeck / simple-runtypes

Small, efficient and extendable runtype library for Typescript
MIT License
114 stars 5 forks source link

`trim` string option causes optional fields to be returned with `undefined` values #100

Closed nicktalb closed 10 months ago

nicktalb commented 1 year ago

See the following test cases:

(1) Without trim option - optional fields are correctly not returned as they are not defined in the input.

// Returns { ok: true, result: {} } ✅
st.use(st.partial(st.record({ name: st.string({ trim: false }), other: st.string() })), {})

(2) With trim option - all optional fields incorrectly returned with undefined values.

// Returns { ok: true, result: { name: undefined, other: undefined } } ❌
st.use(st.partial(st.record({ name: st.string({ trim: true }), other: st.string() })), {})

Many libraries will treat the two objects differently which can cause downstream issues.

hoeck commented 1 year ago

Thanks for reporting this :+1: that indeed is a problem and not the intended behavior.

hoeck-cs commented 11 months ago

Damn, trim and minLength / maxLength are also broken in combination.

Trimming should be done first and min/max length checking should be done on the trimmed string, not on the untrimmed string:

const s = st.string({trim: true, minLength: 1, maxLength: 3})

s(' ') === '' // true, should raise an error instead because '' is not long enough
s('abc ') // raises an error but should not because 'abc' is still within maxLength

Gotta fix that too :sweat_smile: