#"variable used before being assigned" not caught
26 messages · Page 1 of 1 (latest)
Preview:```ts
// we're not allowed to do this
/*
function badf() {
var x : number;
return x; // error: "x" used before being assigned
}
console.log(badf() + 42);
//*/
// but we're allowed to do this...
function f(): () => number { // add "| undefined" to "number" and it errors...
...```
is this a bug, or am i missing something? very new to typescript
!:9998 this is because of the limitation of narrowing not being tracked across function boundaries
i guess i'm confused about the strictNullChecks option -- it seems like that should imply that the type of "var x : number" is actually "number | undefined" unless it can be narrowed later in the function (for example, by assigning a number to x)
in the page on narrowing in the docs it talks about "observed type" versus "declared type". the behavior i'm seeing seems to imply that a variable's observed type (in this case, undefined) isn't always guaranteed to fit inside its declared type (here, number)
Understand how TypeScript uses JavaScript knowledge to reduce the amount of type syntax in your projects.
You're allowed to do this:
function f() {
var x: number;
return () => x;
}
``` but not ```ts
function f() {
var x: number;
return x;
}
``` because in the first case you are not returning a value, but a function that returns that value
Hence why it doesn't complain about not being defined. Still it returns undefined, so undefined + 42 = NaN
Why not use something like this?
function badf(x :number){
return x
}
console.log(badf(7) + 8)
sometimes something like this pattern is used:
function makeThing() {
const T = {};
var stored;
T.get = function() {
return stored;
};
T.set = function(newvalue) {
stored = newvalue;
};
return T;
}
i realize that a class might be an option here, and then strictPropertyInitialization would catch this problem
but that doesn't help me with an existing codebase
What do you want?
how is this narrowing? there's no conditional
i want to understand (:
(referring to the f() in my original example)
I think this is just a case where the compiler can't really analyze to check if this pattern is being used safely.
It's the sort of pattern that's not safe, but occasionally useful so the compiler allows it.
👆 It doesn't look like @typescript-eslint even has a rule for this because a fairly niche issue
Best case we could create a rule that says "don't create let variables without an initialiser unless they have undefined in their type". But IDK if there's huge amounts of value in that.
Also relevant, it looks like the suggestion is to just turn on init-declarations which will force you to add = /* something */ to all your declarations which makes this a moot point.
ah great, thank you!
i see also this https://github.com/microsoft/TypeScript/issues/30053