Skip to content

Breaking change in string enum member type in v3.6 #33403

Closed
@aoberoi

Description

@aoberoi

In order to check whether a given string is a member of a string Enum, I use the code shown below. There seems to be an unintentional breaking change in v3.6.2 and later - this code compiles just fine in v3.3.x - v3.5.x.

Search Terms: enum, includes, string enum

Code

enum Colors {
  Red = 'red',
  Green = 'green',
  Blue = 'blue',
}

const a: string = 'orange';
const b = Object.values(Colors); // in <3.6: any[], in >=3.6 Color[]
const c = Object.values(Colors).includes(a)

Expected behavior: Compiles successfully 👍

Actual behavior: Error on L9 (on call site for includes(...))

Argument of type 'string' is not assignable to parameter of type 'Colors'.ts(2345)

The Object.values type definition doesn't change across these versions, and is the following:

interface ObjectConstructor {
    /**
     * Returns an array of values of the enumerable properties of an object
     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
     */
    values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];

    /**
     * Returns an array of values of the enumerable properties of an object
     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
     */
    values(o: {}): any[];
}

So it seems that string Enums have begun to match the interface { [s: string]: T } where they didn't before. I can understand why it might, but is this intended?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions