Skip to content

Conversation

@thromel
Copy link

@thromel thromel commented Dec 15, 2025

Fixes #62896

Problem

In strict mode, function declarations can only appear at the top level of a script, module, or function body, or inside a block. Code like if (true) function f() {} is a syntax error in strict mode, and JavaScript engines throw:

"In strict mode code, functions can only be declared at top level or inside a block."

However, TypeScript was not reporting this error, allowing invalid code to pass compilation.

"use strict";
if (true) function f() {}
f() // Runtime error: In strict mode code, functions can only be declared at top level or inside a block

Fix

Added a check in the binder to detect when a function declaration is a direct child of a statement node and report error TS1256 in strict mode.

The affected statement types are:

  • IfStatement
  • WhileStatement
  • DoStatement
  • ForStatement
  • ForInStatement
  • ForOfStatement
  • WithStatement
  • LabeledStatement

Examples

// Errors in strict mode (TS1256)
if (true) function f1() {}
while (true) function f2() {}
do function f3() {} while (false);
for (;;) function f4() {}
for (let x in {}) function f5() {}
for (let x of []) function f6() {}
label: function f7() {}

// Valid - function inside a block
if (true) { function g() {} }

// Valid - top level
function topLevel() {}

Test

Added tests/cases/compiler/functionDeclarationAsStatementInStrictMode.ts covering all error and valid cases.

…t mode

Fixes microsoft#62896

In strict mode, function declarations can only appear at the top level of
a script, module, or function body, or inside a block. Code like
`if (true) function f() {}` is a syntax error in strict mode but TypeScript
was not reporting it.

This change adds a check in the binder to detect when a function
declaration is a direct child of a statement node (IfStatement,
WhileStatement, DoStatement, ForStatement, ForInStatement, ForOfStatement,
WithStatement, or LabeledStatement) and reports error TS1256.
@github-project-automation github-project-automation bot moved this to Not started in PR Backlog Dec 15, 2025
@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Dec 15, 2025
Update the fix to report the error regardless of strict mode context,
as TypeScript assumes strict mode at all times. Also improved the error
message to be more helpful: "Function declarations are not allowed
inside statements. Use a block statement to wrap the function declaration."
@thromel
Copy link
Author

thromel commented Dec 15, 2025

@RyanCavanaugh In the issue you mentioned "now that we assume strict mode at all times, this can be a proper parse error."

I've implemented this to report unconditionally (regardless of the inStrictMode flag in the binder), since TypeScript assumes strict mode at all times. However, I noticed other similar checks like with statements still check inStrictMode:

function checkStrictModeWithStatement(node: WithStatement) {
    if (inStrictMode) {
        errorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
    }
}

Could you elaborate on whether this new check should:

  1. Report unconditionally (current implementation) - treating it as a parse error regardless of strict mode context
  2. Only report when inStrictMode is true - consistent with other strict mode checks

Happy to adjust based on your guidance!

@jakebailey
Copy link
Member

since TypeScript assumes strict mode at all times

This is not actually the case. I don't think we should do this until 7.0.

@jakebailey
Copy link
Member

Hm, no: #54500

Probably should only report when isStrictMode is true, but we will just remove that option in a later PR (or, earlier?)

@typescript-bot typescript-bot added For Milestone Bug PRs that fix a bug with a specific milestone and removed For Backlog Bug PRs that fix a backlog bug labels Dec 15, 2025
Per @jakebailey's feedback, TypeScript does not assume strict mode at
all times. The error should only be reported when inStrictMode is true,
consistent with other strict mode checks like 'with' statements.

Updated the error message to mention strict mode and updated baselines
accordingly.
@thromel
Copy link
Author

thromel commented Dec 16, 2025

@jakebailey Thanks for the clarification! I've updated the PR to only report the error when inStrictMode is true, consistent with other strict mode checks.

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

Labels

For Milestone Bug PRs that fix a bug with a specific milestone

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

Using declarations like a statement leads to strange bugs.

3 participants