Skip to content
New issue

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

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

Already on GitHub? # to your account

Function unexpectedly allows returning arguments object directly if it's a superset of the return type #22982

Closed
jdmunro opened this issue Mar 29, 2018 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@jdmunro
Copy link

jdmunro commented Mar 29, 2018

TypeScript Version: 2.8.1

Search Terms:

strict interface return check

Code

interface A {
    firstName: string
    lastName: string
}

interface B {
    firstName: string
}

const worksButMaybeShouldnt = (a: A): B => a // I expected an error here but none occurs

const correctlyFails = (a: A): B => ({...a}) // I expected this error

Expected behavior:

I expected the worksButMaybeShouldnt function to have a compile error. It returns an object that has a different shape to the expected return type (it has an extra property: lastName). The correctlyFails example does something similar, effectively returning a copy of the input, and this correctly exhibits a compile error.

I would expect that the above 2 examples would both have compile errors.

Actual behavior:

There is no compile error at all and I'm able to return an object with a different shape (a superset of the return type).

Playground Link: http://www.typescriptlang.org/play/#src=interface%20A%20%7B%0D%0A%20%20%20%20firstName%3A%20string%0D%0A%20%20%20%20lastName%3A%20string%0D%0A%7D%0D%0A%0D%0Ainterface%20B%20%7B%0D%0A%20%20%20%20firstName%3A%20string%0D%0A%7D%0D%0A%0D%0Aconst%20worksButMaybeShouldnt%20%3D%20(a%3A%20A)%3A%20B%20%3D%3E%20a%20%2F%2F%20I%20expected%20an%20error%20here%20but%20none%20occurs%0D%0A%0D%0Aconst%20correctlyFails%20%3D%20(a%3A%20A)%3A%20B%20%3D%3E%20(%7B...a%7D)%20%2F%2F%20I%20expected%20this%20error%0D%0A

Related Issues:

#3823
#391

@ghost
Copy link

ghost commented Mar 29, 2018

Duplicate of #12936 -- by default all types in TypeScript support subtyping and there's no way to turn it off. There's an exception for object literals since if you write const o: A = { ... } we assume you only intend to write properties in A, but not for variables.

@RyanCavanaugh RyanCavanaugh reopened this Mar 29, 2018
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Mar 29, 2018
@RyanCavanaugh
Copy link
Member

This is a bug but in the reverse direction - we shouldn't enforce known property checks on spreaded properties

@ghost
Copy link

ghost commented Mar 29, 2018

@RyanCavanaugh Duplicate of #19775 then

@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created and removed Bug A bug in TypeScript labels Mar 29, 2018
@jdmunro
Copy link
Author

jdmunro commented Mar 29, 2018

Thanks for the explanation! It wasn't obvious to me at first.

const example1 = (a: A): B => {
    const c = { ...a }
    return c // works
}

const example2 = (a: A): B => {
    return { ...a } // error
}

You can circumvent the known property checks on spread properties, whether inadvertently or not, using the above. I imagine the above are intended to have the same behaviour.

@ghost
Copy link

ghost commented Mar 29, 2018

@jdmunro #7547

@microsoft microsoft locked and limited conversation to collaborators Jul 26, 2018
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants