4 ms·
I recently learned that the TS type-checker is unsound on purpose and i am a bit disappointed. http://tryflow.org/#2944d91c10fc5d76faeebbb20cac466a http://tryf
by igl 11y ago
I recently learned that the TS type-checker is unsound on purpose and i am a bit disappointed.
http://tryflow.org/#2944d91c10fc5d76faeebbb20cac466a http://tryflow.org/#2944d91c10fc5d76faeebbb20cac466a Try this snippet in TS.
- recursive 11y agoUndeclared parameters are implicitly "any". You don't need nearly this much code to break. This is equivalently broken: var x: any = {}; x.foo(); Here's the typesafe way: http://tryflow.org/#b5f826e03045f64084cfc74398270e85 http://tryflow.org/#b5f826e03045f64084cfc74398270e85
- altano 11y agoWhy is this line an error?: > var cats : Cat[] = [ new Cat() ]
- deleted 11y ago[deleted]
- DCoder 11y agoIt would not be an error if not for `addToList(cats, new Dog())`. Based on that call, Flow infers that `cats` has to be a `Dog[]`, not `Cat[]`.
- altano 11y agoRegarding the unsoundness-by-default, I wish "--no-implicit-any" was the default but it's really no big thing to just add this flag to any project.
- igl 11y agoStill... why have type inference in the first place if you can not safely utilize it. The argument for having things unsound is "to strike a balance between correctness and productivity". Having to declare types on everything even if it's just generics beats the productivity argument.
- spion 11y agoBecause turning the inference dial up often results with what Flow does: it shows the error at all the wrong places and doesn't show it at the right one. Try adding the types to the function in your Flow example. The error will finally move to the last line i.e. Flow will actually become useful in tracing down the error. http://tryflow.org/#e6512d9c847d504bba8be8b90427ffc3 http://tryflow.org/#e6512d9c847d504bba8be8b90427ffc3 I think Microsoft made the right call to demand function argument types. It doesn't cost very much at all, but it improves error messages tremendously. It might not matter in a tiny example, but I'd bet that Flow's behaviour can be frustrating in a large project.
- igl 11y agoShowing a less accurate error is worse than showing no error? How is that "less" frustrating if you have to find a bug? It does not DEMAND the argument type? Adding it to flow also improves the error message? How is that the right call?
- spion 11y agoShowing a missing type annotation error is better than showing errors at all the wrong places. Showing no errors is a separate argument entirely, and was addressed by the parent poster (noImplicitAny). I will add that I always use TypeScript with --noImplicitAny which indeed does result with TypeScript DEMANDING type annotations for arguments. Of which you complained: > Having to declare types on everything even if it's just generics beats the productivity argument. and to which I respond that 1. its not everything, just function arguments 2. its better to demand function argument types than to show unhelpful error locations. Implicit any is (was) useful for the early migration phase of the project. At that point you (had to) rename everything from JS to TS to use the compiler, and would get a type error for every unannotated function (which might not be a type error at all). The TS team had to choose between: 1. spending a lot of time and effort to get proper deep unification like Flow's working at acceptable performance in a single-threaded process, even without incremental recompilation, or 2. default to a loose "type checker" and provide a gradual tightening valve for users - at the cost of demanding a bit more annotations: for function arguments (and only if the function is not a part of a single expression or statement where the type can be inferred - e.g. types will be inferred for lambdas passed as function arguments) (1) may have been worth it if it actually resulted with useful error messages, however as demonstrated above, it often doesn't. So they went with (2), and I'm glad they did - otherwise I'd have to deal with mostly-unannotated TypeScript codebases that produce useless error messages every time you do some sort of refactoring, or enforce type annotations via conventions / code reviews / linters. Flow's inference is a beautiful marvel of engineering, really, and the type system avoided some legacy TS pitfalls (has safer treatment of nulls, proper union and intersection types from the start) but I'm afraid its not that big of a marvel of practicality.
- deleted 11y ago[deleted]