Skip to content

The number type is assignable to any enum with implicit values #46562

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
gvergnaud opened this issue Oct 28, 2021 · 2 comments
Closed

The number type is assignable to any enum with implicit values #46562

gvergnaud opened this issue Oct 28, 2021 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@gvergnaud
Copy link

Bug Report

πŸ”Ž Search Terms

enum, extends, number

πŸ•— Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about number being assignable to Enum elements.

⏯ Playground Link

https://www.typescriptlang.org/play?ts=4.4.4#code/PTAEHUAsFMDtQCbQGYEtboOagIbzgK4C2ANKNDgMaTkA20RcALqJtEwOQDOuBTA9kRxNUlHLVoBPXFy6pM8Abnjom0NgCcAUISKgAKtC4sA3ltAXQAeVjQS5y-oDu-ewF8tWkKABC0MQRc0KD8yKBMkKg8TsHQAB4ADv4shsYAdDbBSgBGwTiy8rA42fTh-OEwoLDEuRrhkklaTA1ZAIygALwGRizxarAIPNVEtaAA-OEaBMEAXKDI4kEA3F5gHQB8k9Oe3j58VfwsEcGHMHVOONI4GvwEA00t4QBMnVU10HV9cIPdxuNbs3mi2gK28ESi5AAbuICMIjGUAaAABRjACEAEpPFpKPxYH9kHdXki4nNUkx0Z1NmZLKAuE5UExqMi4hTqTTLGIgr8mBlbHM2ez2Rp2AQNPAAESZcUOQUeGXsznBMlpZz8fnywUWYVMUUSqUayxyzWIFA4Ai0Jjq4007xxUCQfL1JJVaCQj5kXIBLmuj7SRWgCFcAgJBL8IIIBG5e14BD0BAGwU4vEsSRzWxuupdOKea2WCI3JwuwsAUQ0Nw0SI44J4XEgt1oEfTH2jIbgHExxo8NI8bhWWgJsCRysy6JWA6HPRVLlH-buSKeAAZR6BvPpIjW6+aELAq07-DBKABrD37BmIfhGMgxgMsekSCoFoA

Playground link with relevant code

πŸ’» Code

// When defining an enum, each element get's automatically assign to an integer
enum Test {
    One,
    Two,
}

// Because of this we expect Test.One to be assignable to the number type
type t1 = Test extends number ? true : false;
// => true

// But not the other way around
type t2 = number extends Test ? true : false;
// this evaluates to true (?!)


const fun = (x: Test) => {
    switch (x) {
        case Test.One: {
            return "One"
        }

        case Test.Two: {
            return "One"
        }

        default: {
            // x has type never, because every case is supposed to be handled
            const y: never = x

            throw new Error('this should never happen')
        }
    }
};

fun(Test.One);
fun(Test.Two);
fun(20); // This shouldn't typecheck, but it does, and it will throw

πŸ™ Actual behavior

the type of an enum defined without providing values for its elements is wrongfully considered a superset of number, which means we can provide any number to a function taking an enum as parameter.

Note that this isn't the case for enum with string values:

enum Test {
    One = "One",
    Two = "Two",
}


type t1 = Test extends string ? true : false;
// => true

type t2 = string extends Test ? true : false;
// => false


const fun = (x: Test) => {
    switch (x) {
        case Test.One: {
            return "One"
        }

        case Test.Two: {
            return "One"
        }

        default: {
            const y: never = x
            throw new Error('this should never happen')
        }
    }
};

fun(Test.One);
fun(Test.Two);
fun("20"); // doesn't typecheck

πŸ™‚ Expected behavior

number shouldn't be assignable to Test.

@MartinJohns
Copy link
Contributor

MartinJohns commented Oct 28, 2021

Duplicate of #26362, which provides plenty of reasoning for this behaviour. Used search terms: enum number in:title

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants