Section 6.3 of the TypeScript spec explains this (emphasis added):
An explicitly typed function whose return type isn't the Void type, the Any type, or a union type containing the Void or Any type as a constituent must have at least one return statement somewhere in its body. An exception to this rule is if the function implementation consists of a single 'throw' statement.
Your function has one reachable return statement, so it satisfies this requirement. If you place the return inside an if (false), it isn't considered, because it is unreachable.
In the event that it terminates without explicitly returning, it will implicitly return a promise for undefined, which is an allowed value for Promise<number> when the strictNullChecks option is not enabled.
This is unrelated to async. The following also compiles without error:
function getData(): number {
if (1 + 1 === 3) {
return 7;
}
}
As does this:
function getData(): number {
if (1 + 1 === 3) {
return undefined;
}
}
What happens if if (data && data.json().length) is false? Does this function return anything?
It returns a promise that resolves to undefined, because it is marked as async, and async functions always return promises.
Note that (as Tom Fenech pointed out before me), using the strictNullChecks causes both your function and the ones in this answer to produce compiler errors, because undefined is not considered to be a possible value of number when that option is enabled.