diff --git a/README.md b/README.md index b3a24f4..ea7990b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Some of these differences are subjective (e.g. error readability), and I'd love | specifying generic parameters during call-time (`f(x)`) | yes [e.g.](http://www.typescriptlang.org/play/#src=function%20someFactory%3CT%3E()%20%7B%0D%0A%20%20return%20class%20%7B%0D%0A%20%20%20%20method(someParam%20%3A%20T)%20%7B%0D%0A%20%20%20%20%20%20%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0A%2F%2F%20how%20to%20invoke%20this%20factory%20with%20a%20defined%20%3CT%3E%3F%0D%0A%0D%0Aconst%20SomeClass%20%3D%20someFactory%3C%7B%20whatever%3A%20string%20%7D%3E()%0D%0Aconst%20someInstance%20%3D%20new%20SomeClass()%0D%0AsomeInstance.method('will-error-here')%0D%0A) | yes (since Flow 0.72) | | specifying generic parameters for type definitions | yes | yes | | typings for public libraries | plenty of well maintained typings | a handful of mostly incomplete typings | -| unique features | | | +| unique features | | | | type spread operator | [shipped](https://github.com/Microsoft/TypeScript/pull/28234) > 3.2rc | [shipped](https://github.com/facebook/flow/commit/ad443dc92879ae21705d4c61b942ba2f8ad61e4d) >=0.42 | | support for nullish coalescing proposal | no | yes | | support for decorators proposal | yes, legacy proposal | only parsing of legacy proposal, no type-checking | @@ -901,6 +901,52 @@ type TotallyMutableFoo = Mutable `Readonly` is a type mapper to make all properties of an object to be readonly. +## Enums +[Official Documentation](https://www.typescriptlang.org/docs/handbook/enums.html) +> Enums allow us to define a set of named constants. Using enums can make it easier to document intent, or create a set of distinct cases. TypeScript provides both numeric and string-based enums. + +Notice that enums emit extra code, meaning its not only a type annotation feature. + +Enums values help with maintainance, you can easily find usages, and rename enum values (compared to string literal types). + +Enum support number as well as string values (also mixure though probably not useful). + +You can get in runtime, an enum value from its name, and its name from the value: +```ts +enum MyEnum { Foo, Bar } + +let nameOfFoo = MyEnum[MyEnum.Foo]; // "Foo" +let valueOfFoo = MyEnum["Foo"]; // 0 +``` + +Enums allow you to get the keys or values, and iterate over them (this example assumes there are only number values): +```ts +enum MyEnum { Foo, Bar } + +const keys = Object.keys(MyEnum).filter(k => typeof MyEnum[k as any] === "number"); // ["Foo", "Bar"] +const values = keys.map(k => MyEnum[k as any]); // [0, 1] +``` + +Control flow is cleverily respected: +- Conditions checking an enum variable's value, will narrow the possible values in the following code branches. +- Conditions checking a union type's enum property, will narrow the union type in the following code branches. +- Will error on illogical conditions. + +Example: +```ts +enum MyEnum { + Foo, + Bar, +} + +function f(x: MyEnum) { + if (x !== MyEnum.Foo || x !== MyEnum.Bar) { + // ~~~~~~~~~~~~~~~~ + // Error! This condition will always return 'true' since the types 'MyEnum.Foo' and 'MyEnum.Bar' have no overlap. + } +} +``` + # Flow-only concepts ## Inferred existential types