Repository navigation
Consider resolving of Control flow analysis's confusing with type mismatches in initialization #9886
Description
Activity
var o1: A<void> | B<void> = new B<void>(); // error ... var o3: A<void> | B<void>; o3 = new B<void>(); // ok
If assignment at the point of declaration was an error, but the same assignment on the line after the declaration was ok, wouldn't that also be a confusing/unclear behaviour?
falsandtru commented
on Jul 22, 2016 ContributorAuthorMore actionsIt means
const o1: A<void> | B<void> = new B<void>(); // error let o3: A<void> | B<void>; ... o3 = new B<void>(); // ok
Another,
function f(o: A<void> | B<void> = new B<void>()) { // ok o = new A<void>(); // ok }
function f(o: A<void> | B<void> = new B<void>()) { o = new A<void>(); }
This currently compiles fine. Are you suggesting it should be an error? If so, how else could you declare a default value for a parameter that had a union type?
falsandtru commented
on Jul 22, 2016 ContributorAuthorMore actionsIt is a correct case. Updated that example.
So the last line in this example would be an error under this suggestion?
type Optional<T> = Some<T> | None; interface None { readonly none: string; } interface Some<T> { readonly some: T; } const none : None = { none: '' }; class Foo {/***/} let maybeFoo: Optional<Foo> = none; // becomes an error?
falsandtru commented
on Jul 22, 2016 ContributorAuthorMore actionsYes, it needs an assertions. You shouldn't modify variables under this suggestion, and should use
constinstead oflet.let maybeFoo: Optional<Foo> = none; // error let maybeFoo: Optional<Foo> = <Optional<Foo>>none; // ok
you shouldn't modify variables under this suggestion, and should use
constinstead oflet.This doesn't appear consistent with your original suggestion, which shows an example of a
letvariable being modified from one type to another (o3), and doesn't use anyconstvariables.Bear in mind that
constvariables must have initializers, and your suggestion here is to make it an error to use initializers on union-typed variables.I'd say it's unclear at best what problem this is solving and what kind of code you are aiming to encourage here. Perhaps you could revise the suggestion to show the kind of use of
constvariables that you are proposing?- addedDeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionDomain: Error MessagesThe issue relates to error messagingThe issue relates to error messagingand removedDomain: Error MessagesThe issue relates to error messagingThe issue relates to error messaging
on Jul 22, 2016 DanielRosenwasser commented
on Jul 22, 2016 MemberMore actionsI really can't come up with a practical case for where this is desirable. I don't know of any situations where I locally want to tell the type system that I don't want it to know the actual type at a given location.
The best thing I can imagine is when you're just trying to experiment with code to see what the apparent members are of a complex type, but in those cases, you can just use the
declarekeyword to make your declarations ambient.- addedSuggestionAn idea for TypeScriptAn idea for TypeScript
on Jul 22, 2016 - locked and limited conversation to collaborators
on Jun 19, 2018
Adding
--strictInitializationnew option is helpful to clear behaviors of Control flow analysis.Problem
CFA is not clear when declaration type and initialization type are not a same type.
related: #9859
Solution
Disallow initialization by different type.