Closed
Description
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?