Scoping of variables

Topics: General
Nov 1, 2012 at 3:52 PM

During the migration of some JS code to TS I found out that TS compiler doesn't really scope variables correctly. What I mean with that is that it doesn't scope variables to the function level.  An example of an error I made that went undetected:

import path = module("path");

function foo() {
  ... 
  var path = path.join(".....","....."); 
  ... 
}

TS is happy with the above code snippet. Of course what happens when you run this code is that "var path" has actually function level scope and as a result path.join doesn't know the join method. 


Of course I should have used a different name than "path", but still it would be great if the TS compiler could detect these type of errors. On the other hand I guess it is not trivial to support the above since it means rearranging the AST.


//Peter

Nov 1, 2012 at 10:34 PM

Did some more testing, looks like the compiler only don't detect "var abc = abc" type of mistakes.

Most other scenarios are flagged correctly. For example

var x = 12;

function foo() {
     x = 13; 
     var x:string;
}

 

Coordinator
Nov 6, 2012 at 6:44 PM

Variable scoping behaves the same in TypeScript as in JavaScript.  In cases like "var abc = abc.xyz", type inference tries to infer the type of "abc" from the right hand side expression.  Since that expression references the variable being declared, it infers "any".  While in these simple cases it seems clear that this is a programmer error, other cases are not as clear:

var abc = function() { return abc; }

var abc = (function() { return abc; }).xyz

Type inference currently handles all of these in a uniform way, inferring 'any'. 

Keeping this item active to track adding additional static analysis to identify the more clearly incorrect cases here, like the original repro.

Nov 6, 2012 at 7:38 PM

Thanks for the explanation and indeed it does now make sense to me and is indeed consistent.

Just an idea, perhaps the static analysis could warn about invoking properties/methods on non-initialized variables. That feature would have warned me what was actually going on here. Especially since non-initialized variables (without any type info that is) are inferred "any", you also don't get any other warnings till you try to run the code.

(of course only those cases that could be easily determined).