Freewalker
Freewalker

Reputation: 7315

Why doesn't TypeScript catch that a const is being used before assignment?

I have a very simple example where TypeScript (3.5.1) is fine with the code, but it immediately throws an error when run.

I believe the issue here is that essentially value is declared but not initialized prior to getValue running. This is pretty unintuitive imo but I understand this is how JS works.

However, why can't TS detect this issue in such a simple example? Since value is a const, it seems to me TS should be able to determine exactly when it's set and predict that this code crashes.

console.log(getValue());

const value = "some string";

function getValue() {
  return value;
}

In a second example without a function call, TS does catch that the variable is used before assignment:

console.log(value);
const value = "some string";

TSLint's no-use-before-declare also does not appear applicable.

Assuming TS/linting will not be able to catch this, is there a best practice to apply in the initial example that will avoid this crash? "Always declare module-level consts at top of file" for example.

Upvotes: 10

Views: 1408

Answers (2)

Kokodoko
Kokodoko

Reputation: 28128

I think the arrow function answer above answers your question the best, but just as a sidenote: deciding on a strict workflow will also prevent hoisting errors: declare vars, declare functions, call init function:

const value = "some string"

function startApp() { 
    console.log(getValue());
}

function getValue() {
    console.log("yo " + value)
    return value;
}

startApp()

Upvotes: 0

danielnixon
danielnixon

Reputation: 4268

You could enable tslint's only-arrow-functions and then replace your function getValue() with

const getValue = function(): string {
  return value;
}

or even

const getValue = (): string => value;

At that point your first line will be a compiler error:

Block-scoped variable 'getValue' used before its declaration

Upvotes: 3

Related Questions