Skip to content

Enabling @typescript-eslint/no-use-before-define in the eslint-plugin #318

@emileber

Description

@emileber

Overview

I'd like to enforce @typescript-eslint/no-use-before-define in our projects and before extending the config on our side, I was wondering why it was turned off by default and if it could be turned on in this package instead?

Type

  • New feature
  • Changes to existing features

Motivation

While TypeScript prevents most usage before the identifier is actually defined, there are cases that aren't caught and these lead to confusing code using identifiers and types before they're defined, like in the following:

// Uses `MyEnum` type and `myFunction` before they're defined.
const test: MyEnum = myFunction();

// Function implementation hidden away, using hoisting.
function myFunction() {
  // Uses an enum value before it is defined.
  return MyEnum.Test;
}

// While TypeScript catches `const` and `let` usage, it doesn't catch type defs and enums by default.
enum MyEnum {
  Test,
}

I don't believe relying on hoisting is a good practice. I personally see hoisting as a side-effect of JS parsing engines, not an actual feature we should use in code meant for humans. There are edge-cases where hoisting is necessary, these exceptions should probably be highlighted by a eslint-disable-next-line comment.

With the following settings

"@typescript-eslint/no-use-before-define": [
  "error", 
  { 
    "enums": true,
    "typedefs": true, 
    "ignoreTypeReferences": false 
  }
]

...the reversed usage order is made clear.

image

⚠️ That said, enabling this rule would probably break a lot of projects relying on hoisting.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions