Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

empty return statement should be a compiler error when return type is specified #5916

Closed
tejacques opened this issue Dec 3, 2015 · 12 comments · Fixed by #7358
Closed

empty return statement should be a compiler error when return type is specified #5916

tejacques opened this issue Dec 3, 2015 · 12 comments · Fixed by #7358
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@tejacques
Copy link

Currently this function compiles just fine

function foo(x): string {
    return;
}

I understand that it's happening because undefined is a valid result for a variable of type string, and this sort of related back to #185, but a midway point could be to simply require the return statement to not be empty.

Similarly, this code fails to compile:

function foo(x): string {
}

But this one compiles:

function foo(x): string {
    if(false) {
        return;
    }
}

I think the expected behavior is that every branch should require an explicit return statement.

A side benefit of this is that you can get exhausting matching completeness basically for free:

function foo(x: number | string | boolean): string {
    if(typeof x === 'number') {
        return x.toString();
    } else if (typeof x === 'string') {
        return x;
    }
}

Currently the above compiles, but if TypeScript required an explicit return in every branch for non void return functions, there would be a compiler error because there are remaining types in the union. However this would compile:

function foo(x: number | string | boolean): string {
    if(typeof x === 'number') {
        return x.toString();
    } else if (typeof x === 'string') {
        return x;
    } else if (typeof x === 'boolean') {
        return ''+x;
    }
}

This is pretty nice! There is one edge case still -- because of the implicit void included in x, calling foo(null) or foo(undefined) will return undefined. I don't know what to do about this because it relates pretty heavily to #185. I think for now it can be ignored, and whatever resolution that (hopefully) happens there will take care of it.

@vladima
Copy link
Contributor

vladima commented Dec 3, 2015

function foo(x: number | string | boolean): string {
    if(typeof x === 'number') {
        return x.toString();
    } else if (typeof x === 'string') {
        return x;
    }
}

as a note, currently if you compile this code snippet using current bits from master branch with --noImplicitReturns flag you'll get error

test.ts(1,45): error TS7030: Not all code paths return a value.

@tejacques
Copy link
Author

Ah -- that's exactly what I was looking for. Thanks @vladima! I'm guessing this will be in 1.8.0?

@mhegazy
Copy link
Contributor

mhegazy commented Dec 3, 2015

yes. And it is already in typescript@next

@mhegazy
Copy link
Contributor

mhegazy commented Dec 3, 2015

so does this take care of the issue in OP?

@DanielRosenwasser
Copy link
Member

I don't entirely think so; this does't cover accidentally omitting a return expression. But I shouldn't put words in @tejacques' mouth, so I'll let him speak for himself. 😄

@mhegazy
Copy link
Contributor

mhegazy commented Dec 3, 2015

we can make --noImplicitReturns flag return statements with no expression if the function return type is not void or any. not sure if that would be too restrictive though.

@tejacques
Copy link
Author

@DanielRosenwasser is right -- this is really close now, but I would like to see an expression required.

I personally don't think it's too restrictive because the programmer has already declared their intent by specifying a return type on the function. If it remains as a flag, then doubly-so because it is opt-in. It's also a lot clearer that it is intentionally returning undefined if it is explicitly written out.

@mhegazy
Copy link
Contributor

mhegazy commented Dec 3, 2015

@vladima thoughts?

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Jan 7, 2016
@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Feb 1, 2016
@RyanCavanaugh RyanCavanaugh added this to the Community milestone Feb 1, 2016
@RyanCavanaugh RyanCavanaugh added the Good First Issue Well scoped, documented and has the green light label Feb 1, 2016
@RyanCavanaugh
Copy link
Member

Accepting PRs. Make this an error only under the noImplicitReturns flag

@basarat
Copy link
Contributor

basarat commented Mar 3, 2016

Just for the interest of people here. Note the original example:

function foo(x): string {
    return;
}

will automatically be an error in --strictNullChecks : #7140 as I understand 🌹

@mhegazy mhegazy modified the milestones: TypeScript 2.0, Community Mar 3, 2016
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Mar 3, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Mar 3, 2016

thanks @martine!

@nbarnwell
Copy link

Should this not be allowed?

function foo(x): void {
    return;
}

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants