title: Typescript break vs return behavior in recursive function
body: <p>Below are two Typescript functions used to <a href="https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#using-the-type-checker" rel="nofollow noreferrer">recursively walk a source file's abstract syntax tree (AST)</a>. I have managed to identify the problem that caused my program to only visit part of the tree, but I do not understand <em>why</em> the solution works.</p>
  
  <p>The <code>walkTree1</code> function is the valid solution that walks the entire tree. The <code>walkTree2</code> function only visits part of the tree. The two functions differ only by one line (marked with comment), and obviously the <code>return</code> behavior ties into this somehow, but I didn't find anything useful online.</p>
  
  <pre><code>function walkTree1(firstNode: ts.SourceFile, visitor: (node: ts.Node) =&gt; void): void {
    visitInterfacesRecursive(firstNode);
  
    function visitInterfacesRecursive(node: ts.Node): void {
      switch (node.kind) {
        case ts.SyntaxKind.InterfaceDeclaration:
          visitor(node); break; // correct
        default:
          ts.forEachChild(node, visitInterfacesRecursive);
      }
    }
  }
  
  function walkTree2(firstNode: ts.SourceFile, visitor: (node: ts.Node) =&gt; void): void {
    visitInterfacesRecursive(firstNode);
  
    function visitInterfacesRecursive(node: ts.Node): void {
      switch (node.kind) {
        case ts.SyntaxKind.InterfaceDeclaration:
          return visitor(node); // offending change
        default:
          ts.forEachChild(node, visitInterfacesRecursive);
      }
    }
  }
  </code></pre>
  
  <p>At long last, I am stumped. I feel like I'm missing something obvious here. I have inspected the generated source and there doesn't seem to be any surprises there (no real difference except type erasure). For now I'm posting the original code; if necessary I'll put together something more reproducible when I get home later.</p>
  
  <p>Additional details:</p>
  
  <ul>
  <li><code>node -v</code> : v8.5.0</li>
  <li><code>tsc -v</code> : Version 2.3.4</li>
  <li><a href="https://github.com/Microsoft/TypeScript/blob/v2.3.4/src/compiler/parser.ts#L53" rel="nofollow noreferrer"><code>ts.forEachChild</code> source</a></li>
  </ul>