Not All Code Paths Return a Value in TypeScript

I’ve been working on a TypeScript implementation of the Oware variant of Mancala, and ran across an interesting case which is currently NOT a compiler error in TypeScript v1.7:

public MakeMove(board: Board): boolean {
		var pos = this.clickedPosition;
		this.clickedPosition = null;
 
		if (null === pos) {
			return false;
		}
 
		if (this.id === pos.player) {
			if (board.GetStones(pos) > 0) {
				var finalDrop = board.Sow(pos);
				board.Capture(pos.player, finalDrop);
			} else {
				alert("Select a house with at least 1 stone!");
			}
		} else {
			alert("Select a house from your side!");
		}
	}

If you can’t see the error, don’t worry, I didn’t see it either until I tried to run the game.  Basically, I forgot to return the result of trying to make the move.  Stupid error, simple fix.  What was interesting is that there was no error thrown by the compiler, and no option to force an error.  To further the mystery, if you remove all return statements:

public MakeMove(board: Board): boolean {
		//..
		if (null === pos) {
			//return;   ERROR! ERROR!
		}
		//..
	}

You get the expected error:

Build: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.

You will also get the expected type error if you try to return something other than the declared return type, but if you use an empty return statement, the compiler is happy:

public MakeMove(board: Board): boolean {
		//..
		if (null === pos) {
			return// No errors here!
		}
		//..
	}

A little searching led me to this issue entered last year, where the reasoning behind this behavior was explained.  Basically a lot of existing and correct JavaScript code relies on the fact that JavaScript returns undefined when a function doesn’t explicitly return a value, so if TypeScript forced all code paths to return a value, then that existing JavaScript would become an error.

This was somewhat frustrating.  One of the best things about TypeScript is that by adding type annotations, the compiler can catch simple mistakes such as these.  Fortunately, the TypeScript team apparently agrees and decided to add an opt-in compiler flag in v1.8 to handle this type of situation.  I guess that gives me another reason to love working with TypeScript.