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

ternary operator with an empty object always gives an empty object #14758

Closed
zpdDG4gta8XKpMCd opened this issue Mar 21, 2017 · 9 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@zpdDG4gta8XKpMCd
Copy link

zpdDG4gta8XKpMCd commented Mar 21, 2017

const data = Math.random() > 0.5 ? { value: 1 } : { }; 
// expected data to be {} | { value: number }, actual data is {}
@zpdDG4gta8XKpMCd zpdDG4gta8XKpMCd changed the title ternary operator with an empty objects and a object literal gives an empty object ternary operator with an empty object always gives an empty object Mar 21, 2017
@gcnew
Copy link
Contributor

gcnew commented Mar 21, 2017

I think its caused by subtype reduction. Unfortunately {} is really poisonous.

I've stumbled upon a similar issue, where because of #13039 (comment) the reduction is unsafe: #12970.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label May 24, 2017
@jurosh
Copy link

jurosh commented Aug 14, 2017

It's really dangerous, also code like this which looks to be properly typed can silently introduce errors to codebase:

interface IObject {
  foo?: boolean;
}

const fooBar: IObject = true ? {
  foo: 'not boolean', // should be boolean only
  notExisting: '132' // should not exist
} : {};

It's always taking {}, so we can type everything into fooBar, no matter that we strictly defined IObject as constant type.

@mhegazy mhegazy added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 16, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Oct 16, 2017

{} is a super type of {value: number}, and {} | {value:number} is the same as {} from assignability point of view.

@zpdDG4gta8XKpMCd
Copy link
Author

by the same logic 6 | false is {} too which is a super type

@mhegazy
Copy link
Contributor

mhegazy commented Oct 16, 2017

well, yes, {} is the top type.

@zpdDG4gta8XKpMCd
Copy link
Author

i love your sense of humor, dear sir

@OliverJAsh
Copy link
Contributor

How come this behaviour only applies to ternary operators, not functions?

    // expected error, but got none!
    const x2: { blur?: string } = 'foo' ? { blur: 1 } : {};

    // expected error, got error
    const x3: { blur?: string } = (() => {
        if ('foo') {
            return { blur: 1 };
        } else {
            return {};
        }
    })();

@RyanCavanaugh
Copy link
Member

Tracking this at #19236

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus and removed Working as Intended The behavior described is the intended behavior; this is not a bug labels Oct 26, 2017
@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created and removed In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Oct 30, 2017
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

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

No branches or pull requests

7 participants