Skip to content

Use-before-assigned analysis does not account for functions returning never #11666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tjhance opened this issue Oct 15, 2016 · 3 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@tjhance
Copy link

tjhance commented Oct 15, 2016

TypeScript Version: 2.0.3

Code

With --strictNullChecks,

function throwError(): never {
  throw new Error();
}

let a: number;

if (Math.random() > 0.5) {
  a = 5;
} else {
  throwError();
}

console.log(a);

Expected behavior:

I expect that, since throwError has return type never, that TypeScript would be able to deduce through control flow analysis that a has been initialized when console.log(a) is called.

(This works as expected if the throwError(); line is replaced with the more direct throw new Error().)

Actual behavior:

I get an error

a.ts(13,13): error TS2454: Variable 'a' is used before being assigned.

@aluanhaddad
Copy link
Contributor

There is a difference between a function typed as () => never and to saying that a call to that function implies always throws. But practically, I guess they mean the same thing.

If the compiler were to do this, wouldn't it also make sense that calling such functions unconditionally should change the callers inferred return type to never? That does not happen today, I don't know if it is by design.

function f(): never {
  throw Error();
}
function g() {
  f();
}

In the above f has type () => never, but only because I annotated it as such, while g has type () => void. If you were reviewing this code, you would probably think that calling g indicates a programmer error unless it actually through some conventional NotImplemenetedError.

@gcnew
Copy link
Contributor

gcnew commented Oct 16, 2016

TypeScript uses the shape of the code, not the types in this case. See #10973 and #10973 (comment)

PS: This crops up every now and then, maybe the TS team will revisit whether they can make it work.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 17, 2016

indeed a duplicate of #10973

@mhegazy mhegazy added the Duplicate An existing issue was already created label Oct 17, 2016
@mhegazy mhegazy closed this as completed Apr 21, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants