Skip to content

Bug: Boolean type literals misbehaving #10432

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

Closed
benjamin-hodgson opened this issue Aug 19, 2016 · 3 comments · Fixed by #10577
Closed

Bug: Boolean type literals misbehaving #10432

benjamin-hodgson opened this issue Aug 19, 2016 · 3 comments · Fixed by #10577
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@benjamin-hodgson
Copy link

TypeScript Version: nightly (2.1.0-dev.20160818)

Code
I lifted this from Anders's final example in #9407 (comment).

type Result<T> = { success: true, value: T } | { success: false };

function foo(): Result<number> {
    if (someTest()) {
        return { success: true, value: 42 };
    }
    else {
        return { success: false };
    }
}
function someTest(): Boolean { return true; }

Expected behavior:
Type-checks OK

Actual behavior:
Type error:

result.ts(5,16): error TS2322: Type '{ success: boolean; value: number; }' is not assignable to type 'Result<number>'.
  Type '{ success: boolean; value: number; }' is not assignable to type '{ success: false; }'.
    Types of property 'success' are incompatible.
      Type 'boolean' is not assignable to type 'false'.
result.ts(8,16): error TS2322: Type '{ success: boolean; }' is not assignable to type 'Result<number>'.
  Type '{ success: boolean; }' is not assignable to type '{ success: false; }'.
    Types of property 'success' are incompatible.
      Type 'boolean' is not assignable to type 'false'.

If I add manual type annotations (true as true, false as false) to the success assignments it works:

function foo(): Result<number> {
    if (someTest()) {
        return { success: true as true, value: 42 };
    }
    else {
        return { success: false as false };
    }
}

The bug only affects Boolean literals. If I use enum, number, or string type literals it works - for example:

type Result<T> = { success: 1, value: T } | { success: 0 };

function foo(): Result<number> {
    if (someTest()) {
        return { success: 1, value: 42 };
    }
    else {
        return { success: 0 };
    }
}
@bchenSyd
Copy link

not fully fixed....

type Result<T> = { success: true, value: T } | { success: false };

function foo(): Result<number> {
    if (someTest()) {
        return { success: true, value: 42 }; //OK
       return Object.assign({}, { success: true, value: 42 })  // type 'boolean' is not assignable to type 'true'
    }
    
}

@RyanCavanaugh
Copy link
Member

@bochen2014 I don't see how we could fix that case. In general we don't assume that functions won't modify a type within its own domain, and the true value gets quickly widened to boolean here because it's not used in a position where it's known to not be mutated.

@bchenSyd
Copy link

hi Ryan, thanks for your reply.
Just so you know that I've walked around the issue by

return {
success: true, 
value :42,
...someObject
}

which does the same as Object.assign

@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
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants