From 3a634a771caa812a9ca22a3a4dc927d639a4e9f5 Mon Sep 17 00:00:00 2001 From: Itay Ronen Date: Tue, 20 Aug 2019 18:13:05 +0300 Subject: [PATCH 1/5] Typescript Enums Added a typescript unique feature: Enums --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b3a24f4..72635b0 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,34 @@ 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. + +Enums are more maintainable compared to literal types. You can easily find usages, and rename enum values. + +Enum support number as well as string values (also mixure though probably not useful). + +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 E { + Foo, + Bar, +} + +function f(x: E) { + if (x !== E.Foo || x !== E.Bar) { + // ~~~~~~~~~~~ + // Error! This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap. + } +} +``` + # Flow-only concepts ## Inferred existential types From 1d000575cbd257769d0f71c5e74afb92463f936f Mon Sep 17 00:00:00 2001 From: Itay Ronen Date: Sun, 25 Aug 2019 11:56:22 +0300 Subject: [PATCH 2/5] Review fixes and additions --- README.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 72635b0..ad8b872 100644 --- a/README.md +++ b/README.md @@ -905,10 +905,28 @@ type TotallyMutableFoo = Mutable [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. -Enums are more maintainable compared to literal types. You can easily find usages, and rename enum values. +Notice that enums emits 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, value, and iterate over them: +```ts +enum MyEnum { Foo, Bar } + +let keys = Object.keys(MyEnum); // ["Foo", "Bar"] +let values = Object.values(MyEnum); // [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. @@ -916,15 +934,15 @@ Control flow is cleverily respected: Example: ```ts -enum E { +enum MyEnum { Foo, Bar, } -function f(x: E) { - if (x !== E.Foo || x !== E.Bar) { - // ~~~~~~~~~~~ - // Error! This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap. +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. } } ``` From 488d476577613c772b3e4ba691d96aee89db5604 Mon Sep 17 00:00:00 2001 From: Itay Ronen Date: Sun, 25 Aug 2019 11:59:26 +0300 Subject: [PATCH 3/5] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad8b872..4da8b49 100644 --- a/README.md +++ b/README.md @@ -905,7 +905,7 @@ type TotallyMutableFoo = Mutable [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 emits extra code, meaning its not only a type annotation feature. +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). From 90758b1a936f3a6eb9dd7442d42f412ad8f7e7e2 Mon Sep 17 00:00:00 2001 From: Itay Ronen Date: Sun, 25 Aug 2019 12:01:32 +0300 Subject: [PATCH 4/5] Fix another typo - value to values --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4da8b49..c22da15 100644 --- a/README.md +++ b/README.md @@ -919,7 +919,7 @@ let nameOfFoo = MyEnum[MyEnum.Foo]; // "Foo" let valueOfFoo = MyEnum["Foo"]; // 0 ``` -Enums allow you to get the keys, value, and iterate over them: +Enums allow you to get the keys or values, and iterate over them: ```ts enum MyEnum { Foo, Bar } From f38f096b0fbea69a2cb690d793f2b13ebc9e6b45 Mon Sep 17 00:00:00 2001 From: Itay Ronen Date: Sun, 25 Aug 2019 12:49:30 +0300 Subject: [PATCH 5/5] Fix incorrect example --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c22da15..ea7990b 100644 --- a/README.md +++ b/README.md @@ -919,12 +919,12 @@ let nameOfFoo = MyEnum[MyEnum.Foo]; // "Foo" let valueOfFoo = MyEnum["Foo"]; // 0 ``` -Enums allow you to get the keys or values, and iterate over them: +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 } -let keys = Object.keys(MyEnum); // ["Foo", "Bar"] -let values = Object.values(MyEnum); // [0, 1] +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: