Skip to content

typescript: bind/call/apply answers the strict regime on a module compiled non-strict #416

Closed

Description

@swapnilpaliwal-sd

Priority: P2, two sites moved SOUND_SUPERSET → WRONG when more of a dependency became resolvable. The engine's set previously contained the compiler's answer and now does not.

What happens

const routerMethodRef = this.routerMethodFactory
  .get(router, requestMethod)
  .bind(router);
oracle  lib.es5.d.ts:296:5                      Function.bind
engine  lib.es5.d.ts:357:5; lib.es5.d.ts:393:5  CallableFunction.bind

lib.es5.d.ts declares bind twice, on Function, and again on CallableFunction extends Function, and strictBindCallApply is the only thing that decides which one the compiler answers with. cases/22-loose-bind-call-apply exists for exactly this regime, and tools/tsc_oracle_case.mjs carries a long note on why a case must be able to state the flag rather than inherit a hardcoded one.

The project is mixed: 188 of its modules carry strictBindCallApply = true and 97 carry false. The two sites are in the false group, and the engine answers as though they were strict.

Why it surfaced now

It is not a regression from the change that exposed it (#414). Before that, the receiver \.get(...)`did not resolve, sobind` fell back to a set that happened to contain the right declaration. Once the dependency was staged properly the receiver acquired a type, the overload pair became distinguishable, and the flag started deciding, wrongly.

So this is latent wherever a receiver is typed and the module is non-strict; it was simply unreachable before because the receiver was not typed. Expect it to appear at more sites as resolution improves, which is the wrong direction for a rate to move.

What to check first

ts_module column 27 carries the resolved flag per module, and the parser populates it, the mixed 188/97 split above is read straight off it. So the information is present; the question is whether the overload rules read it at all, or read it from the wrong module (the DECLARING module of bind, which is lib.es5.d.ts and has no meaningful value, rather than the module of the CALL SITE).

That distinction is the likely answer and is cheap to test: both sites are in the same file, and a third bind call in a strict module of the same project should answer differently if the flag is being read per call site.

Activity

  1. swapnilpaliwal-sd commented on Sep 29, 2026

    @swapnilpaliwal-sd
    ContributorAuthor

    Fixed by #1783 (merged into 0.1.9).

  2. swapnilpaliwal-sd commented on Sep 29, 2026

    @swapnilpaliwal-sd
    ContributorAuthor

    Fixed by #1783 (merged into 0.1.9).

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

Metadata

Metadata

Labels

bugSomething isn't workingtypescriptTypeScript

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions