-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Setting defaults breaks type check #74
Comments
With ObjectModel Edit: on second try of this example I again do not get an error, but I should... |
Seems to be connected to |
Some more tests with
with no defaults: on
with default value for
|
Oh that's a big one. I'm surprised it didn't get spotted by the 433 unit tests. NEED MORE TESTS ! Thanks for the report, I'm looking at this today |
Ok here is what's happening: const Person = Model({
name: String,
age: [Number]
}).defaults({
name: "new-name"
});
Person.test(1) // true ! Why is 1 considered a valid Person ? Because object model validation is based on the types of its defined properties. X is a valid Person if X.name is a String and X .age a Number or undefined.
So you might say, yes, the definition of its properties is valid, but 1 is not an object ! Well, it can be. JavaScript has this ability to dynamically convert its primitive types to objects when needed. That's why you can call methods on numbers like this : Now, what we could do is add an assertion to object models so that they must be objects or derived from objects, without casting. But this is a breaking change and it breaks some existing mechanics like null-safe object traversal, so I need to think about how do to this properly. |
I think I found a proper solution. To be released in v3.5 |
Thanks for your explanation - makes sense!
Just my thoughts, I don't know if it makes sense or is possible to implement without breaking something. But since you said you already found a solution - great! |
3.5 has been released, you can test it already. The test I added is relatively safe and sensible, but I expect it to break some part of some project somewhere. We'll see 🙈 The purpose of the Also, a common misunderstanding about default values is that they are not set as the properties of the object itself, but instead are defined on the prototype: const Person = Model({ name: String }).defaults({ name: "Anonymous" });
let rick = new Person({ name: "Rick Sanchez" })
console.log(rick.name); // Rick Sanchez
delete rick.name;
console.log(rick.name); // Anonymous, inherited from Person.prototype.name |
Ok, then I did not correctly understand the
I think this would work without errors, because Thanks for the new release, unfortunately I will not be able to use it, because I do not want to drop IE support on my project, so I'm currently using version |
Ah, ok, I think now i understand - its because of the "duck typing". |
I'll try to report a similar fix on v2, but I can't promise it will behave exactly the same. I don't understand what your goal is in turning off the duck-typing/auto-casting feature. To be clear, passing My point is that the autocasting provided by ObjectModel doesn't make your type-checking "less strict", it's just more convenient. In the end, it's the same model definition that applies. |
I reported this fix in v2, with the v2.6.3 version. Could you confirm ir works as intended ? Thanks |
Thanks for also fixing this in
But in some cases it would maybe make sense to have a stricter form. Think about this example:
And instances of these models are serialized and stored as JSON somewhere. Now if in the step of deserializing one would accidentally use a
However if there would be any kind of stricter parsing, one would be able to detect such an error, e.g.:
What I was suggesting before, was that the constructor |
I can not imagine a scenario where someone would like to instantiate models, while being certain that his data will not use the default values specified in the model. If you are certain of that, then extend the model and remove the defaults, problem solved. Also, having a special method that does not apply the defaults would not solve the underlying problem: unless the Car Model is sealed, it is possible to have a Car with a |
ok, I think you are right. I'm just thinking too much about strict type checking like it is possible in typed languages. But it's probably simply not possible to achieve that by dynamic checks in javascript. However your library is a great help, thanks for that! |
Yeah, static and dynamic type-checking are very different, the same concepts can not apply. |
yes, very good! |
I encounter the problem that setting default values of an ObjectModel breaks the type check. See the following demonstration:
[1,2,3]
instead of a validPerson
object results in the expected error in the console:Uncaught TypeError: expecting wife[0] to be { name: String, age: [Number] }, got Number 1
Person
ObejctModel, suddenly there is no type error anymore for setting wife to[1,2,3]
.I tested ObjectModel
v3.4.6
in Chrome Version67.0.3396.79
and Firefox60.0.2
The text was updated successfully, but these errors were encountered: