Let's see an example:
export async function foo(): Promise<string>{
await bar()
return;
}
It piles without an error.
Then,
export async function foo(): Promise<string>{
await bar()
}
results in error
A function whose declared type is neither 'void' nor 'any' must return a value
1) Why?
I guess it is something with .md#63-function-implementations
and plicated by using async, typescript and its typing?
UPDATE:
FYI, when function has return;
has not return
(or even has return undefined;
), it is the same situation from the semantics perspective, right?
Let's see an example:
export async function foo(): Promise<string>{
await bar()
return;
}
It piles without an error.
Then,
export async function foo(): Promise<string>{
await bar()
}
results in error
A function whose declared type is neither 'void' nor 'any' must return a value
1) Why?
I guess it is something with https://github./Microsoft/TypeScript/blob/master/doc/spec.md#63-function-implementations
and plicated by using async, typescript and its typing?
UPDATE:
FYI, when function has return;
has not return
(or even has return undefined;
), it is the same situation from the semantics perspective, right?
- 1 If you define a return type then you need a return statement. " it is the same situation from the semantics perspective" No. It has the effect in JavaScript but it's semantically different in TypeScript. Otherwise you wouldn't get that error. – a better oliver Commented May 9, 2018 at 14:30
- Can you send me a link to a documentation saying this, please? – WojtylaCz Commented May 9, 2018 at 14:39
5 Answers
Reset to default 4This is not really related to async/await
the empty return is treated as return undefined
. So this also works:
function foo(): string{
return; // equivalent to return undefined;
}
If you use strictNullChecks
you will get an error as undefined
is not assignable to string
If you omit the return pletely the piler would infer the return type as void
which is different from the declared type of string
and thus this would be an error. Same applies if the function is async
and returns a Promise
The point of explicitly providing a return type other than Void
or Any
is that you want to ensure type safety. And you implicitly tell the piler that you actually want to return something. That's why the piler expects you to do this and plains when you don't. It's defined in the TypeScript specification section 6.1:
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
As for your question concerning return
, you are right.
return;
and return undefined;
have the same oute, that's defined by the ECMAScript specification section 13.10:
If Expression is omitted, the return value is undefined.
Omitting the return
statement also has the same effect, as defined in section 9.2.1. Step 11 basically says that undefined
is returned if nothing else has been returned (Step 9) or no exception has been thrown (Step 10).
So while your examples lead to the same result (returning undefined
) in JavaScript, they are semantically different for the TypeScript piler (the second ex. doesn't return anything).
If you really want to have strict type checking you should set
"strictNullChecks": true
in you tsconfig.json
file.
when you have a function like this
async function (): Promise<string> {
return; // same as return undefined
}
if your tsconfig.json
doesn't have `strictNullChecks" set to true, then piling will pass through without an error.
Check docs/handbook/piler-options.html
You have to use Promise<void>
if you don't plan on returning the Promise.
By using the return type annotation (: Promise<string>
) you are saying that the function will return something (a Promise that may resolve to a string at some future point), so a function without a return
statement clearly goes against that annotation/intent.
To mark the function as not returning anything, you may use the annotation : void
instead, but this may cause a different error about not being able to coerce undefined to a Promise), so in this case : Promise<void>
may be more appropriate.
It doesn't matter in your example that you have an empty return
expression, because with an async
function, if you return a non-promise value, it will automatically be wrapped in a promise, so the return;
will still be correct from the piler's perspective.