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

Discriminated unions over enum members don't error as expected when used with number literals #12647

Closed
rotemdan opened this issue Dec 4, 2016 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@rotemdan
Copy link

rotemdan commented Dec 4, 2016

TypeScript Version: nightly (2.2.0-dev.20161203)

Code:

const enum E { Hey, Ho }

type A = {
	x: E.Hey;
	y: string;
}

type B = {
	x: E.Ho;
	y: number;
}
var zzz: A | B = { x: 1, y: "hello" }; // Doesn't error
var zzz: A | B = { x: 54, y: "hello" }; // Doesn't error

Expected behavior:
Should error.

Actual behavior:
Doesn't error.

For comparison:

type A = {
	x: 0;
	y: string;
}

type B = {
	x: 1;
	y: number;
}
var zzz: A | B = { x: 1, y: "hello" }; // Errors as expected
/*
'Type '{ x: 1; y: string; }' is not assignable to type 'A | B'.
  Type '{ x: 1; y: string; }' is not assignable to type 'B'.
    Types of property 'y' are incompatible.
      Type 'string' is not assignable to type 'number'.'
*/

var zzz: A | B = { x: 54, y: "hello" }; // Errors as expected
/*
'Type '{ x: 54; y: string; }' is not assignable to type 'A | B'.
  Type '{ x: 54; y: string; }' is not assignable to type 'B'.
    Types of property 'x' are incompatible.
      Type '54' is not assignable to type '1'.'
*/
@rotemdan rotemdan changed the title Discriminated unions over enum members don't error as expected when substituted with number literals Discriminated unions over enum members don't error as expected when used with number literals Dec 4, 2016
@normalser
Copy link

I think it's rather about "feature" of enums - #11559

const enum E { Hey, Ho }
const a: E.Hey = 54 // // Doesn't error

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

I am seeing a related error in similar situation -

const enum kinds {
    first,
    second,
}

interface IFData {
    kind: kinds.first;
    data: string;
}

interface ISData {
    kind: kinds.second;
    data: number;
}

type Data = IFData | ISData;

function checker(input: Data) {
    const { kind, data } = input;
    switch (kind) {
        /**
         * Property 'length' does not exist on type 'string | number'.
         * Property 'length' does not exist on type 'number'.
         * ^ Above error on following case line
         */
        case kinds.first: return data.length;

        /**
         * Property 'length' does not exist on type 'string | number'.
         * Property 'length' does not exist on type 'number'.
         * ^ Above error on following case line
         */
        case kinds.second: return Math.abs(data);
    }
}

Discriminated unions with enum kinds do not seem to work as I expected. Can anyone suggest possible correction other than going back to literal string kinds ?

@RyanCavanaugh
Copy link
Member

@sushruth narrowing doesn't work once the discriminant is picked off into its own variable via destructuring

@sushruth
Copy link

Yeah, I kind of figured that. It would have been awesome if it did work.

@RyanCavanaugh RyanCavanaugh 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 Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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

4 participants