-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write more about Object definition differences for the same code #8
Comments
It's not less safe, it provides exactly the same amount of safety. There is nothing unsafe in having extra properties |
I have to disagree here. export type Car = {
brand: string,
color?: 'red' | 'blue',
}
const car : Car = { brand: 'Tesla', colour: 'red' } In TypeScript you'd spot the typo immediately ( Another example where it is less safe: function storeInDatabase(car: Car) {
db.insert(car)
// I can be sure that 'car'
// has only the expected properties
// nothing more, nothing less
// since nothing can ever be added by mistake
}
storeInDatabase({ brand: 'Tesla', color: 'red', thing: 123 }) |
Right, this is a typo, but it's unsafe, it doesn't lead to runtime errors.
Once again, objects are not exact in Typescript. Exact means that it is guaranteed that object doesn't have properties other than declared. This is a unique feature of Flow. Typescript catches additional properties when "fresh" object is assigned to annotated variable or passed to a function directly. Other than that it allows additional properties and doesn't guarantee anything. Using your example: type Car = {
brand: string,
color: string,
}
function storeInDatabase(car: Car) {
db.insert(car)
// I can be sure that 'car'
// has only the expected properties
// or can I?
}
const car = { brand: 'Tesla', color: 'red', thing: 123 };
storeInDatabase(car); |
@vkurchatkin ok, that clears it up for me. Many thanks. I don't think 'no runtime errors' should be the end-goal though. I think type safety, like strictness of definitions (and not allowing additional properties) could save us headaches in many cases like those cited above. Given that, it's a shame Flow doesn't use the safer, strict / closed types by default, and only allows to have "open" types when explicitly defined. TypeScript default is still a tiny bit better than the Flow one, so in order from best safety to worst:
|
Preventing typos is non-goal for Flow, but it is for Typescript. "No runtime errors" is the definitions of safety. Exact types are useful only in a limited amount of cases, because they are not subtype-able. Saying that that exact objects are just better is the same as saying that not having subtyping is better. |
@vkurchatkin I get that Flow's definition of safety is "no runtime errors", but I don't think that covers it. To me, typos are just as part of programming safety, as are extraneous properties - and if we're being specific, both of those can cause runtime errors. E.g. to reference the previous case: a database driver throwing an error after being passed an object with an extraneous, unexpected field present. Definitely not an edge case, and it classifies as a runtime error, no? Unless we use the comfortable definition of "only built-in errors", which is, to be honest kinda cheating. Couldn't exact types could work with subtyping, if one could use destructuring syntax to extend types, and/or if you could annotate a non-exact version of the object for explicit non-exact use? |
You confuse safety with correctness.
No, they cannot. That's the point.
Well, first of all, this is actually covered but Flow's exact type. Secondly, there is no way to prevent a library from throwing an error if it wants to. You can't encode every possible runtime check as a type.
Not sure what you mean |
Perhaps there's a useful row in the initial table based on this discussion
|
@RyanCavanaugh I agree, I'll add this. Thanks. |
[DRAFT]
In TS you don't get "loose" properties on your objects, since you can't assign more than your definition expects:
TS's above object's-exact-by-default stance might get you to design better APIs, unless you want to go and slap $Exact everywhere in your Flow code. This doesn't mean Flow is less-type-safe, it's just that this default is less safe than in TS. There are other cases where the opposite is true (TS's defaults being weaker-typed) then Flow.
The text was updated successfully, but these errors were encountered: