diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 49a17d6a5..47416bcc1 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -1462,7 +1462,12 @@ export abstract class LuaTranspiler { const identifierName = this.transpileIdentifier(node.name); if (node.initializer) { const value = this.transpileExpression(node.initializer); - return `local ${identifierName} = ${value}`; + if (ts.isFunctionExpression(node.initializer) || ts.isArrowFunction(node.initializer)) { + // Separate declaration and assignment for functions to allow recursion + return `local ${identifierName}; ${identifierName} = ${value}`; + } else { + return `local ${identifierName} = ${value}`; + } } else { return `local ${identifierName} = nil`; } diff --git a/test/translation/lua/shorthandPropertyAssignment.lua b/test/translation/lua/shorthandPropertyAssignment.lua index fb515bf23..5246c7435 100644 --- a/test/translation/lua/shorthandPropertyAssignment.lua +++ b/test/translation/lua/shorthandPropertyAssignment.lua @@ -1 +1 @@ -local f = function(x) return ({x = x}) end; +local f; f = function(x) return ({x = x}) end; diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index f370cbd83..45bea8645 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -245,4 +245,28 @@ export class FunctionTests { Expect(result).toBe(3); } + + @Test("Recursive function definition") + public recursiveFunctionDefinition(): void { + const result = util.transpileAndExecute( + `function f() { return typeof f; } return f();`); + + Expect(result).toBe("function"); + } + + @Test("Recursive function expression") + public recursiveFunctionExpression(): void { + const result = util.transpileAndExecute( + `let f = function() { return typeof f; } return f();`); + + Expect(result).toBe("function"); + } + + @Test("Recursive arrow function") + public recursiveArrowFunction(): void { + const result = util.transpileAndExecute( + `let f = () => typeof f; return f();`); + + Expect(result).toBe("function"); + } }