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

Doesn't work type checking for function arguments #11058

Closed
iKBAHT opened this issue Sep 22, 2016 · 5 comments
Closed

Doesn't work type checking for function arguments #11058

iKBAHT opened this issue Sep 22, 2016 · 5 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@iKBAHT
Copy link

iKBAHT commented Sep 22, 2016

TypeScript Version: 1.8.0 / nightly (2.0.0-dev.201xxxxx)

Code

function fn(options: { a?: number, b?: boolean }) {
    return options.a || 1;  
}

fn('foo');

Expected behavior:
Must be an error in

fn('foo');

Actual behavior:
No errors, TS compiler say "OK".

@nippur72
Copy link

I guess what's happening here: since a and b are optional, the resulting type is similar to {}. Now {} in TypeScript is a type with no members whatsoever, so anything will cast to it.

Indeed it's possible to write:

'foo' as {}; // ok

@yortus
Copy link
Contributor

yortus commented Sep 22, 2016

As @nippur72 points out, this is a consequence of function argument bivariance, where if a parameter expects a type X, then you can pass a subtype or a supertype of X with no errors.

In this case, the type string satisfies the requirements of {a?: number, b?: boolean}, since no particular properties are required to do so. It is thus a subtype and so due to bivariance, it's valid to pass a string as the options argument.

What you seem to want in this example is parameter invariance, i.e. the exact type with no extra props. TS doesn't support that.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 22, 2016

An interface with all optional arguments is just like one that is empty. an empty interface matches anything, including strings. see https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-all-types-assignable-to-empty-interfaces for details.

@holiber
Copy link

holiber commented Oct 23, 2016

It is not intuitive behavior. Flowjs works as expected https://flowtype.org/try/#0GYVwdgxgLglg9mABMMAKOAHWCDOAuRAb0QEMB+AsEAWwCMBTAJwBpFaK244AbekpAL4BKIgChG9KCEZJM2MDgB0JRAB9ViAIwBuRKIGjRKVAHJgXE0O1A

@Igorbek
Copy link
Contributor

Igorbek commented Nov 4, 2016

@mhegazy you right, however at the same time TS disallows "extra" properties:

function fn(options: { a?: number, b?: boolean }) {
    return options.a || 1;  
}

fn('foo'); // ok
fn({ c: 1; }); // error even though { c: number; } is assignable to { a?: number; b?: boolean; }

the reason you do this is to catch common errors, right? so must be done here.

@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
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

6 participants