I discovered a neat trick I while reading TypeScript's source code.
.NET developers call it FlagsAttribute.
enum ColorFlags {
None = 0,
Red = 1 << 0,
Yellow = 1 << 1,
Purple = 1 << 2,
Blue = 1 << 3,
Brown = 1 << 4,
}
This little snippet has a lot going on, so let's unpack it
The <<
symbol is the left shift operator. It takes the binary representation of the value on the left and shifts every bit N-times where N is the number on the right.
const a = 5; // 00000101
a << 1 === 10; // 00001010
a << 2 === 20; // 00010100
a << 3 === 40; // 00101000
If we use 1
as the left operand, something interesting happens: we get the powers of two. This means that the binary representation of the number will have only one bit set to 1
, and the rest will be zero.
1 << 0; // 00000001
1 << 1; // 00000010
1 << 2; // 00000100
1 << 3; // 00001000
This means that the initial snippet could be rewritten as this:
enum ColorFlags {
None = 0,
Red = 1,
Yellow = 2,
Purple = 4,
Blue = 8,
Brown = 16,
}
The question is: why do this?
Imagine we want to allow only some colors to be used and that the list of allowed colors is dynamic—perhaps passed as a configuration object. Then, we can use the bitwise OR |
operator to code this:
const AllowedColors = ColorFlags.Red | ColorFlags.Yellow | ColorFlags.Blue;
// 0001 | 0010 | 1000 = 1011
Let's say that we get a color
as a parameter, and we want to do something if this color is Red
, but only if Red
is one of the allowed colors. We can now do this:
if ((AllowedColors & color) === ColorFlags.Red) {
// do something
}
If color is allowed, the bitwise AND &
will return its code; otherwise, it will return zero, which we mapped to the value None
in our enum.
Here you can see this technique being used in TypeScript's codebase: types.ts