Skip to content

Generic arrow bindings inside functions: uses that run before the initializer diverge from Node #1642

Open

Description

@ejc3

Since #1627, a generic arrow binding inside a function compiles to module-level instances, and its declaration emits no initialization. Uses that can run before the declaration then diverge from Node. Main at 1ee5c84:

  1. A closure above the declaration (annotated binding):
function make(): (x: number) => number {
  const read = (): ((x: number) => number) => id;
  const id: (x: number) => number = <T>(x: T): T => x;
  return read();
}
console.log(make()(7));

Node prints 7; the binary throws ReferenceError: Cannot access 'id' before initialization.

  1. A function declaration below the binding, which is hoisted:
function outer(flag: boolean): number {
  if (flag) return helper();
  const id: (x: number) => number = <T>(x: T): T => x;
  return helper();

  function helper(): number {
    return id(1);
  }
}
console.log(outer(false));

Node prints 1; the binary throws the same ReferenceError.

  1. A class extends expression in a closure above the declaration:
class Base {}
function select(n: number) {
  console.log(n);
  return Base;
}
function run() {
  const before = () => {
    class Derived extends select(id(1)) {}
    new Derived();
  };
  const id: (x: number) => number = <T>(x: T): T => x;
  before();
}
run();

Node prints 1; the binary prints nothing and exits 0.

  1. A var assigned in a branch that does not run:
function run(flag: boolean): number {
  if (flag) {
    var id = <T>(x: T): T => x;
  }
  const invoke = (): number => id(1);
  return invoke();
}
console.log(run(false));

Node throws TypeError: id is not a function; the binary prints 1.

Compiling the binding only when it is a const declared directly in a block, with no value reference above it or inside a function declaration of the block (class extends expressions included), and refusing it otherwise, covers these four.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions