Reputation: 61167
Typescript does not give a compiler error for the following code:
var b = a + 10; // Why no compilation error here
var a = 10;
alert(b.toString());
I would expect the first line to be an error as I have not declared or initialized var a till this time.
If I remove the second line I get the compiler error.
I know its valid in JavaScript but I would expect TypeScript to give me compilation error or warning.
Upvotes: 8
Views: 2859
Reputation: 276299
Assuming you understand that your code is equivalent to:
var a, b
b = a + 10
a = 10
alert(b.toString())
Which in turn is equivalent to:
var a = undefined, b = undefined
b = a + 10
a = 10
alert(b.toString())
The reason why it should be allowed is because undefined is a valid value for a variable that you can assign and read.
There are various use cases where this functionality is valuable. E.g The module pattern used in typescript:
module x{
export var foo;
}
Generates javascript code that exploits this fact:
var x;
(function (x) {
x.foo;
})(x || (x = {})); //x was never assigned but used in "x ||" part
This is left in TypeScript due to JavaScript backward compatibility (not to mention it is useful).
Here is a purely TypeScript usecase. Perhaps you want to pass undefined into a function call (this is valid typescript):
var a:number = undefined; // same as simply "var a"
console.log(a);
It is just assumed that the TypeScript developer wants the power of the underlying JavaScript language.
This is not the case for languages where Reading before Assignment is invalid (e.g C#). In C# an unassigned variable has no meaning. In JavaScript it does. So TypeScript has to allow this.
Upvotes: 6
Reputation: 11849
Because hoisting behavior can be confusing. Your code actually means.
var a, b
b = a + 10
a = 10
alert(b.toString())
There are valid reasons to allow hoisting, but they don't involve var
, but function
- you can call function declared later.
alert(identity(i))
function identity(i) {
return i
}
In this case, alert
uses result of function declared later. Thanks to hoisting behavior, it works.
While I agree this case should have an warning (not error, TypeScript wants to be compatible with JavaScript), it doesn't appear that TypeScript currently notices that. Every variable in TypeScript has a type that CANNOT change during lifetime of variable, and in your case, a
is number
type (it isn't aware that you use it before assignment, because var
sets type implicitly). TypeScript assumes it's a number, even if it's not, because of its declaration.
You may want to report this as a bug in TypeScript.
Upvotes: 10