Function return value constraints

Topics: Language Specification
Oct 12, 2013 at 10:15 AM
A logical assumption was posted in the form of issue 1778 where the author expects a function, marked explicitly with a return type, with code branches which lead to an inconclusive return value, not to compile. In fact, I expected the same behavior and yet the issue was closed with the mention that this behavior (allowing no return value on a function with an explicit return value) to compile.

In code:
function x1():number { } // this compiles
Not only is this a source for bugs in the actual implementation. More so, this will lead to confusion for the consumer or this method. If no conclusive return value was to be allowed, we would expect a function declaration with the return type annotated by an ?, just like that of an optional parameter:
function x1():number? { } // seems logical to compile
When inferring the return type, one can simply look if all code branches lead to a conclusive return value (or raise an exception for that matter).

Why is the current specification of return values designed the way it is?
Oct 13, 2013 at 4:40 PM
Edited Oct 13, 2013 at 4:41 PM
In JavaScript it is perfectly valid to "fall out" of a function. It causes the value 'undefined' to be returned, and 'undefined' is in the domain of every type. So, it really becomes an issue of where to put the dial on classifying valid JavaScript functions as errors. We've found that it is almost always an error when there no return statements anywhere in the function body, but beyond that we start to see too many false positives and it turns into an exercise in silencing errors that aren't really errors. It's all about balancing pros and cons. We may at some point introduce stricter modes of checking, but probably not for 1.0.
Oct 14, 2013 at 2:33 AM
Edited Oct 14, 2013 at 2:39 AM
Thanks for the reply. I understand the implication of enforcing a valid return type within javascript, therefore I've proposed to allow to the user to declare the return type as optional, in a same way as parameters and members can (in context) be marked optional by appending a ? to the name. This would lead to a number of implications:
function a(){ return 0; } // type inference will resolve a required numeric return type here which gives consumers a form of guarantee that without exceptional cases, the function will always return a numeric value

function b() { if (a) return 0; } // type inference will resolve an optional numeric return type

function c(): numeric { return 0; } // this is perfectly valid and will have the same implications as function a

function d(): numeric { if (a) return 0; } // this will simply not compile for a numeric return type is enforced

function e(): numeric? { if (a) return 0; } // this is allowed for the return type is marked optional(syntax to be disputed)
the impact of this will logically not only help for quality check on the functions implementation but moreover will give a scenario where its clarity from the function declaration alone will give you enough details on whether to expect undefined results.
Oct 14, 2013 at 8:56 PM
I'm also wondering why the compiler doesn't have better bug detection around return types. It seems like allowing missing return statements and having undefined leak everywhere and start generating NaNs is a lot worse than just forcing a return statement with a valid value. What is an example of a use case where it's better to just "fall out" of a function?
Jul 5, 2014 at 8:02 PM
Edited Jul 6, 2014 at 3:40 PM
Anders Hejlsberg said that there are pros and cons to every options! Clearly this would not create a balance as there are more cons than there are pros!
Obviously TypeScript is a javascript typed superset, I can imagine having a poor written function [without return value on all code path] could potentially break other codes and I'm talking null-reference errors, type mismatch, NaN, ... that could be catastrophic in the deployed code!
The fact is that when I'm using a TypeScript code in an explicitly typed expression, I don't need all the ugly plumbings, input or type validation, undefined checking, ... I want to be sure to write a code that couldn't break the way a dynamic language like javascript could!

The following is a valid JavaScript code and it could compile within TypeScript
function SomeMethod() { }
But when you explicitly mention that the method returns something, the least the compiler should do is to throw an error, if not why bother preventing this code from compiling in the first place?
function SomeMethod(): number { }
The followings are all wrong in a typed context yet the compiler ignores them as a valid code:
function SomeMethod(): number {

function SomeMethod(): number {
    return null;

function SomeMethod(): number {
    if (false)
        return 1;

function SomeMethod(): number {
    try {
    catch (ex) {
        return 0;
Apr 27, 2015 at 2:00 AM
Edited Apr 27, 2015 at 2:04 AM
Hejlsberg's answer is positioning the dial based on existing JavaScript code.

For users lucky enough to be developing entirely new codebases strictly in TypeScript allowing e.g.:
function foo(): boolean { return; }
to pass without any way to have it flagged does hurt. Lack of compile-time safety net resulting in e.g. undefined propagation is the very reason I don't work in JavaScript. Coming from the warm safety of Java and C# errors like the above clobber me and are in fact my only disappointment so far w/ TypeScript.

Give us something -- a strictness level, a warning message, a toast, something. Heck even if I had to set the strictness level at the top of every file I could handle it. Being able to manually turn that dial up a bit in strictness would make TypeScript feel a lot better.