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

Arrow function with wrong return type relative to explicit signature does not cause compiler errors. #21674

Closed
brunnerh opened this issue Feb 6, 2018 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@brunnerh
Copy link

brunnerh commented Feb 6, 2018

TypeScript Version: 2.8.0-dev.20180206

Search Terms:
wrong return type arrow function
inferred type arrow function

Code

// Does not compile, because the signature does not match the inferred return type.
function test1(value: number): void
{
	return value; // error TS2322: Type 'number' is not assignable to type 'void'.
}

// Does compile, type is not correctly inferred, signature is used.
const test2: (value: number) => void
	= (value: number) => value;

test2(42) + 1; // error TS2365: Operator '+' cannot be applied to types 'void' and '1'.

Expected behavior:

test2 fails to compile because the signature does not match the returned object's type, just as test1 does.

Actual behavior:

test2 compiles and uses the explicit signature without error.

Playground Link: [Link]

Related Issues:
#17505 - About argument inference, rather than return type.

@mhegazy mhegazy added the Working as Intended The behavior described is the intended behavior; this is not a bug label Feb 6, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Feb 6, 2018

The first case is clearly a bug. the compiler alerts you that the declared API does not match your implementation..

The second is different, u are allowed to assign something that is more specific to something that is more general.. for instance, var x: Animal = new Dog() is a valid assignment.. similarly, you can assign something that returns a value to one that does not require a value.. the error is correct, since test2 is declared to return a void. that is the same as const x: Animal = new Dog(); x.bark()

@brunnerh
Copy link
Author

brunnerh commented Feb 6, 2018

I understand the reasoning here but i slightly disagree about the statement This is the expected and desired behavior.

To take the example from the FAQ:

function doSomething(): number {
    return 42;
}
function callMeMaybe(callback: () => void) {
    callback();
}
callMeMaybe(doSomething);

This does absolutely nothing, since doSomething is a pure function and callMeMaybe ostensibly expects to be passed a function with side effects, as that is the only thing a function with such a signature could achieve.

This feature of allowing that assignment has just brilliantly masked a coding error that could have been avoided.

Personally, i think another strict flag would be great to make this sort of assignment illegal. To reasonably work with such a flag, something like an ignore function would be useful, so you can make the second example work without much hassle:

let items = [1, 2];
callMeMaybe(() => ignore(items.push(3)));

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Feb 6, 2018

This has been discussed countless times, see #19014, #8240, #8584, #8581, #9603, #8615, #20006, etc

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants