-
Notifications
You must be signed in to change notification settings - Fork 120
t.maybe setting the value to null when missing #183
Comments
Well, this is a very opinionated part of tcomb: my goal was to get rid of Coming to your use case there's something I don't get. Since you are providing a default value, de facto @props({
foo: t.String // <= foo is always a string
})
class MyComponent extends React.Component {
static defaultProps = {
foo: 'bar'
}
...
} Now |
that'd be great in theory, but it clashes with the cruel reality. Javascript works differently, unfortunately, and many other libraries tcomb interoperates with will make the const { foo = 'bar', baz = 'hey' } = { foo: null }
console.log(foo) // null
console.log(baz) // hey
Not sure I agree.
True, in theory, but doesn't the process of validating makes the values to go through the |
I guess it's a matter of taste, such a documentation should also report the presence of a default. That typing is also safer when you refactor the code (say you mistakenly delete
AFAIK no, it doesn't. As a proof scan the import React from 'react'
import ReactDOM from 'react-dom'
import { t, props } from 'tcomb-react'
@props({
foo: t.maybe(t.String)
})
class MyComponent extends React.Component {
static defaultProps = {
foo: 'bar'
}
render() {
return <div>Hello {this.props.foo}</div>
}
}
ReactDOM.render(<MyComponent />, document.getElementById('app')) Output <div data-reactid=".0">
<span data-reactid=".0.0">Hello </span>
<span data-reactid=".0.1">bar</span>
</div> Let's make clear the rationale and the assumptions of this library: tcomb is grounded on math, and specifically on set theory. In JavaScript we often need to express that a value is optional, but how to represent the "absence of a value" in set theory? The empty set is not a good candidate as it contains no elements. So we need to define a conventional set This is perhaps the most opinionated choice in tcomb (actually I'm a little surprised that nobody complained about this choice before so thank you for this discussion). How to represent an "optional string"? The tcomb answer is: an optional string is the set union of two sets: the Now how to represent "default values"? A natural answer would be: given a function
tl;dr Personally I think that having both |
Thank you for the thorough explanation. Regarding the For the theoretical-side of the conversation, you raise an excellent point
but in Javascript
tcomb can be (and it is) mathematically sound internally. Laws are defined in terms of the So, when you define a function
I would expect
Unfortunately, the definition of such function is often beyond the scope of tcomb.
Given |
I agree. The main question now is: would this change be considered a breaking change? |
Yes, I think so. There's a chance somebody out there is relying on
and it would change to
Given that |
@gcanti - Any updates or thoughts on that front? I've started to use tcomb library for this particular server-side code (node.js), it allows me to struct & validate a model before passing through a database query. I've encountered same dilemma as @gabro, where the database query would consider
For now, I'm using this prototypal extension as a workaround: 'use strict';
const _ = require('lodash');
const Person = t.struct({
id: t.maybe(t.String),
}, 'Person');
Person.prototype.toJSON = function () {
let purge = (current) => {
_.forOwn(current, (value, key) => {
if (_.isUndefined(value) || _.isNull(value)) {
delete current[key];
}
});
if (_.isArray(current)) _.pull(current, undefined);
return current;
};
return purge(_.cloneDeep(this)); // Do not modify the original object, create a clone
}; |
Relevant to this discussion. Douglas Crockford on null vs undefined: |
@jaxyeh thanks for reporting. I think that the only reasonable solution is to go ahead with a breaking change and to release a v3.0.0. @gabro Would you like to send a PR for this? |
It's on its way |
Prevent Maybe constructor from altering the value when Nil (fixes #183)
Is there a reason why
t.maybe
sets the value tonull
when missing?This behavior turns a missing value (e.g.
undefined
) into a value (null
) and it looks like a potentially undesirable side-effect.For instance this causes issues with
tcomb-react
: sincenull
is a valid value, React will not use the value provided bydefaultProps
.A more natural implementation would look like
Do you think that's reasonable, @gcanti?
The text was updated successfully, but these errors were encountered: