From 27e620fa8272c742055faeb590034044769f5c1f Mon Sep 17 00:00:00 2001 From: Sven Brodny Date: Thu, 29 Feb 2024 14:38:42 +0100 Subject: [PATCH 1/4] feat(challenge 47): typescript enums vs union types --- README.md | 2 +- .../enums-vs-union-types/.eslintrc.json | 36 ++++++++ .../typescript/enums-vs-union-types/README.md | 13 +++ .../enums-vs-union-types/project.json | 73 +++++++++++++++ .../src/app/app.component.ts | 83 ++++++++++++++++++ .../src/app/app.config.ts | 5 ++ .../enums-vs-union-types/src/assets/.gitkeep | 0 .../enums-vs-union-types/src/favicon.ico | Bin 0 -> 15086 bytes .../enums-vs-union-types/src/index.html | 13 +++ .../enums-vs-union-types/src/main.ts | 7 ++ .../enums-vs-union-types/src/styles.scss | 5 ++ .../enums-vs-union-types/tailwind.config.js | 14 +++ .../enums-vs-union-types/tsconfig.app.json | 10 +++ .../enums-vs-union-types/tsconfig.editor.json | 7 ++ .../enums-vs-union-types/tsconfig.json | 30 +++++++ challenge-number.json | 4 +- .../angular/46-simple-animations.md | 2 - .../typescript/47-enums-vs-union-types.md | 67 ++++++++++++++ docs/src/content/docs/es/index.mdx | 6 +- docs/src/content/docs/fr/index.mdx | 6 +- docs/src/content/docs/index.mdx | 4 +- docs/src/content/docs/pt/index.mdx | 6 +- docs/src/content/docs/ru/index.mdx | 6 +- 23 files changed, 380 insertions(+), 19 deletions(-) create mode 100644 apps/typescript/enums-vs-union-types/.eslintrc.json create mode 100644 apps/typescript/enums-vs-union-types/README.md create mode 100644 apps/typescript/enums-vs-union-types/project.json create mode 100644 apps/typescript/enums-vs-union-types/src/app/app.component.ts create mode 100644 apps/typescript/enums-vs-union-types/src/app/app.config.ts create mode 100644 apps/typescript/enums-vs-union-types/src/assets/.gitkeep create mode 100644 apps/typescript/enums-vs-union-types/src/favicon.ico create mode 100644 apps/typescript/enums-vs-union-types/src/index.html create mode 100644 apps/typescript/enums-vs-union-types/src/main.ts create mode 100644 apps/typescript/enums-vs-union-types/src/styles.scss create mode 100644 apps/typescript/enums-vs-union-types/tailwind.config.js create mode 100644 apps/typescript/enums-vs-union-types/tsconfig.app.json create mode 100644 apps/typescript/enums-vs-union-types/tsconfig.editor.json create mode 100644 apps/typescript/enums-vs-union-types/tsconfig.json create mode 100644 docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md diff --git a/README.md b/README.md index 7ccd5a1..09a91e6 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ If you would like to propose a challenge, this project is open source, so feel f ## Challenges -Check [all 46 challenges](https://angular-challenges.vercel.app/) +Check [all 47 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ diff --git a/apps/typescript/enums-vs-union-types/.eslintrc.json b/apps/typescript/enums-vs-union-types/.eslintrc.json new file mode 100644 index 0000000..8ebcbfd --- /dev/null +++ b/apps/typescript/enums-vs-union-types/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/typescript/enums-vs-union-types/README.md b/apps/typescript/enums-vs-union-types/README.md new file mode 100644 index 0000000..b23e100 --- /dev/null +++ b/apps/typescript/enums-vs-union-types/README.md @@ -0,0 +1,13 @@ +# Enums vs Union Types + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve typescript-enums-vs-union-types +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/typescript/47-enums-vs-union-types/). diff --git a/apps/typescript/enums-vs-union-types/project.json b/apps/typescript/enums-vs-union-types/project.json new file mode 100644 index 0000000..63e9a04 --- /dev/null +++ b/apps/typescript/enums-vs-union-types/project.json @@ -0,0 +1,73 @@ +{ + "name": "typescript-enums-vs-union-types", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/typescript/enums-vs-union-types/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/typescript/enums-vs-union-types", + "index": "apps/typescript/enums-vs-union-types/src/index.html", + "browser": "apps/typescript/enums-vs-union-types/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/typescript/enums-vs-union-types/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/typescript/enums-vs-union-types/src/favicon.ico", + "apps/typescript/enums-vs-union-types/src/assets" + ], + "styles": ["apps/typescript/enums-vs-union-types/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "typescript-enums-vs-union-types:build:production" + }, + "development": { + "buildTarget": "typescript-enums-vs-union-types:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "typescript-enums-vs-union-types:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + } + } +} diff --git a/apps/typescript/enums-vs-union-types/src/app/app.component.ts b/apps/typescript/enums-vs-union-types/src/app/app.component.ts new file mode 100644 index 0000000..12fae6d --- /dev/null +++ b/apps/typescript/enums-vs-union-types/src/app/app.component.ts @@ -0,0 +1,83 @@ +import { Component, computed, signal } from '@angular/core'; + +enum Difficulty { + EASY = 'easy', + NORMAL = 'normal', +} + +enum Direction { + LEFT = 'left', + RIGHT = 'right', +} + +@Component({ + standalone: true, + imports: [], + selector: 'app-root', + template: ` +
+
+ + +
+

Selected Difficulty: {{ difficultyLabel() }}

+
+ +
+
+ + +
+

{{ directionLabel() }}

+
+ `, + styles: ` + section { + @apply flex flex-col mx-auto my-5 w-fit gap-2 items-center; + + > div { + @apply flex w-fit gap-5; + } + } + + button { + @apply rounded-md border px-4 py-2; + } + `, +}) +export class AppComponent { + readonly Difficulty = Difficulty; + readonly difficulty = signal(Difficulty.EASY); + + readonly Direction = Direction; + readonly direction = signal(undefined); + + readonly difficultyLabel = computed(() => { + switch (this.difficulty()) { + case Difficulty.EASY: + return Difficulty.EASY; + case Difficulty.NORMAL: + return Difficulty.NORMAL; + } + }); + + readonly directionLabel = computed(() => { + const prefix = 'You choosed to go'; + switch (this.direction()) { + case Direction.LEFT: + return `${prefix} ${Direction.LEFT}`; + case Direction.RIGHT: + return `${prefix} ${Direction.RIGHT}`; + default: + return 'Choose a direction!'; + } + }); +} diff --git a/apps/typescript/enums-vs-union-types/src/app/app.config.ts b/apps/typescript/enums-vs-union-types/src/app/app.config.ts new file mode 100644 index 0000000..81a6edd --- /dev/null +++ b/apps/typescript/enums-vs-union-types/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/typescript/enums-vs-union-types/src/assets/.gitkeep b/apps/typescript/enums-vs-union-types/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/typescript/enums-vs-union-types/src/favicon.ico b/apps/typescript/enums-vs-union-types/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..317ebcb2336e0833a22dddf0ab287849f26fda57 GIT binary patch literal 15086 zcmeI332;U^%p|z7g|#(P)qFEA@4f!_@qOK2 z_lJl}!lhL!VT_U|uN7%8B2iKH??xhDa;*`g{yjTFWHvXn;2s{4R7kH|pKGdy(7z!K zgftM+Ku7~24TLlh(!g)gz|foI94G^t2^IO$uvX$3(OR0<_5L2sB)lMAMy|+`xodJ{ z_Uh_1m)~h?a;2W{dmhM;u!YGo=)OdmId_B<%^V^{ovI@y`7^g1_V9G}*f# zNzAtvou}I!W1#{M^@ROc(BZ! z+F!!_aR&Px3_reO(EW+TwlW~tv*2zr?iP7(d~a~yA|@*a89IUke+c472NXM0wiX{- zl`UrZC^1XYyf%1u)-Y)jj9;MZ!SLfd2Hl?o|80Su%Z?To_=^g_Jt0oa#CT*tjx>BI z16wec&AOWNK<#i0Qd=1O$fymLRoUR*%;h@*@v7}wApDl^w*h}!sYq%kw+DKDY)@&A z@9$ULEB3qkR#85`lb8#WZw=@})#kQig9oqy^I$dj&k4jU&^2(M3q{n1AKeGUKPFbr z1^<)aH;VsG@J|B&l>UtU#Ejv3GIqERzYgL@UOAWtW<{p#zy`WyJgpCy8$c_e%wYJL zyGHRRx38)HyjU3y{-4z6)pzb>&Q1pR)B&u01F-|&Gx4EZWK$nkUkOI|(D4UHOXg_- zw{OBf!oWQUn)Pe(=f=nt=zkmdjpO^o8ZZ9o_|4tW1ni+Un9iCW47*-ut$KQOww!;u z`0q)$s6IZO!~9$e_P9X!hqLxu`fpcL|2f^I5d4*a@Dq28;@2271v_N+5HqYZ>x;&O z05*7JT)mUe&%S0@UD)@&8SmQrMtsDfZT;fkdA!r(S=}Oz>iP)w=W508=Rc#nNn7ym z1;42c|8($ALY8#a({%1#IXbWn9-Y|0eDY$_L&j{63?{?AH{);EzcqfydD$@-B`Y3<%IIj7S7rK_N}je^=dEk%JQ4c z!tBdTPE3Tse;oYF>cnrapWq*o)m47X1`~6@(!Y29#>-#8zm&LXrXa(3=7Z)ElaQqj z-#0JJy3Fi(C#Rx(`=VXtJ63E2_bZGCz+QRa{W0e2(m3sI?LOcUBx)~^YCqZ{XEPX)C>G>U4tfqeH8L(3|pQR*zbL1 zT9e~4Tb5p9_G}$y4t`i*4t_Mr9QYvL9C&Ah*}t`q*}S+VYh0M6GxTTSXI)hMpMpIq zD1ImYqJLzbj0}~EpE-aH#VCH_udYEW#`P2zYmi&xSPs_{n6tBj=MY|-XrA;SGA_>y zGtU$?HXm$gYj*!N)_nQ59%lQdXtQZS3*#PC-{iB_sm+ytD*7j`D*k(P&IH2GHT}Eh z5697eQECVIGQAUe#eU2I!yI&%0CP#>%6MWV z@zS!p@+Y1i1b^QuuEF*13CuB zu69dve5k7&Wgb+^s|UB08Dr3u`h@yM0NTj4h7MnHo-4@xmyr7(*4$rpPwsCDZ@2be zRz9V^GnV;;?^Lk%ynzq&K(Aix`mWmW`^152Hoy$CTYVehpD-S1-W^#k#{0^L`V6CN+E z!w+xte;2vu4AmVNEFUOBmrBL>6MK@!O2*N|2=d|Y;oN&A&qv=qKn73lDD zI(+oJAdgv>Yr}8(&@ZuAZE%XUXmX(U!N+Z_sjL<1vjy1R+1IeHt`79fnYdOL{$ci7 z%3f0A*;Zt@ED&Gjm|OFTYBDe%bbo*xXAQsFz+Q`fVBH!N2)kaxN8P$c>sp~QXnv>b zwq=W3&Mtmih7xkR$YA)1Yi?avHNR6C99!u6fh=cL|KQ&PwF!n@ud^n(HNIImHD!h87!i*t?G|p0o+eelJ?B@A64_9%SBhNaJ64EvKgD&%LjLCYnNfc; znj?%*p@*?dq#NqcQFmmX($wms@CSAr9#>hUR^=I+=0B)vvGX%T&#h$kmX*s=^M2E!@N9#m?LhMvz}YB+kd zG~mbP|D(;{s_#;hsKK9lbVK&Lo734x7SIFJ9V_}2$@q?zm^7?*XH94w5Qae{7zOMUF z^?%F%)c1Y)Q?Iy?I>knw*8gYW#ok|2gdS=YYZLiD=CW|Nj;n^x!=S#iJ#`~Ld79+xXpVmUK^B(xO_vO!btA9y7w3L3-0j-y4 z?M-V{%z;JI`bk7yFDcP}OcCd*{Q9S5$iGA7*E1@tfkyjAi!;wP^O71cZ^Ep)qrQ)N z#wqw0_HS;T7x3y|`P==i3hEwK%|>fZ)c&@kgKO1~5<5xBSk?iZV?KI6&i72H6S9A* z=U(*e)EqEs?Oc04)V-~K5AUmh|62H4*`UAtItO$O(q5?6jj+K^oD!04r=6#dsxp?~}{`?&sXn#q2 zGuY~7>O2=!u@@Kfu7q=W*4egu@qPMRM>(eyYyaIE<|j%d=iWNdGsx%c!902v#ngNg z@#U-O_4xN$s_9?(`{>{>7~-6FgWpBpqXb`Ydc3OFL#&I}Irse9F_8R@4zSS*Y*o*B zXL?6*Aw!AfkNCgcr#*yj&p3ZDe2y>v$>FUdKIy_2N~}6AbHc7gA3`6$g@1o|dE>vz z4pl(j9;kyMsjaw}lO?(?Xg%4k!5%^t#@5n=WVc&JRa+XT$~#@rldvN3S1rEpU$;XgxVny7mki3 z-Hh|jUCHrUXuLr!)`w>wgO0N%KTB-1di>cj(x3Bav`7v z3G7EIbU$z>`Nad7Rk_&OT-W{;qg)-GXV-aJT#(ozdmnA~Rq3GQ_3mby(>q6Ocb-RgTUhTN)))x>m&eD;$J5Bg zo&DhY36Yg=J=$Z>t}RJ>o|@hAcwWzN#r(WJ52^g$lh^!63@hh+dR$&_dEGu&^CR*< z!oFqSqO@>xZ*nC2oiOd0eS*F^IL~W-rsrO`J`ej{=ou_q^_(<$&-3f^J z&L^MSYWIe{&pYq&9eGaArA~*kA + + + + typescript-enums-vs-union-types + + + + + + + + diff --git a/apps/typescript/enums-vs-union-types/src/main.ts b/apps/typescript/enums-vs-union-types/src/main.ts new file mode 100644 index 0000000..f3a7223 --- /dev/null +++ b/apps/typescript/enums-vs-union-types/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err), +); diff --git a/apps/typescript/enums-vs-union-types/src/styles.scss b/apps/typescript/enums-vs-union-types/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/typescript/enums-vs-union-types/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/typescript/enums-vs-union-types/tailwind.config.js b/apps/typescript/enums-vs-union-types/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/typescript/enums-vs-union-types/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/typescript/enums-vs-union-types/tsconfig.app.json b/apps/typescript/enums-vs-union-types/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/typescript/enums-vs-union-types/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/typescript/enums-vs-union-types/tsconfig.editor.json b/apps/typescript/enums-vs-union-types/tsconfig.editor.json new file mode 100644 index 0000000..4ee6393 --- /dev/null +++ b/apps/typescript/enums-vs-union-types/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": [] + } +} diff --git a/apps/typescript/enums-vs-union-types/tsconfig.json b/apps/typescript/enums-vs-union-types/tsconfig.json new file mode 100644 index 0000000..db0ec0f --- /dev/null +++ b/apps/typescript/enums-vs-union-types/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json", + }, + { + "path": "./tsconfig.editor.json", + }, + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + }, +} diff --git a/challenge-number.json b/challenge-number.json index bba17af..fee6a96 100644 --- a/challenge-number.json +++ b/challenge-number.json @@ -1,6 +1,6 @@ { - "total": 46, - "🟢": 17, + "total": 47, + "🟢": 18, "🟠": 120, "🔴": 209 } diff --git a/docs/src/content/docs/challenges/angular/46-simple-animations.md b/docs/src/content/docs/challenges/angular/46-simple-animations.md index f7c197a..9a92e89 100644 --- a/docs/src/content/docs/challenges/angular/46-simple-animations.md +++ b/docs/src/content/docs/challenges/angular/46-simple-animations.md @@ -6,7 +6,6 @@ challengeNumber: 46 command: angular-simple-animations sidebar: order: 17 - badge: New --- ## Information @@ -45,4 +44,3 @@ Add a stagger animation for the list on the right side. - diff --git a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md new file mode 100644 index 0000000..c214be2 --- /dev/null +++ b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md @@ -0,0 +1,67 @@ +--- +title: 🟢 Enums vs Union Types +description: Challenge 47 is about the comparison between enums and union types +author: sven-brodny +challengeNumber: 47 +command: typescript-enums-vs-union-types +sidebar: + order: 18 + badge: New +--- + +## Information + +[Enums](https://www.typescriptlang.org/docs/handbook/enums.html) allow developers to define a set of named constants that represent a specific type. TypeScript provides both numeric and string-based enums. + +```typescript +enum Difficulty { + EASY = 'EASY', + NORMAL = 'NORMAL', +} +``` + +On the other hand, [Union Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) are simpler than enums, as they don't require any additional runtime or compilation overhead. + +```typescript +type Difficulty = 'EASY' | 'NORMAL'; +``` + +### Reasons to use Union types + +Enums are a conecpt borrowed from languages like C# and Java. TypeScript Enums are compiled into JavaScript objects with keys for both the names and values of the Enum members. This results in larger output files and additional memory consumption, which can be particularly problematic in performance-critical applications. + +Enums have some more pitfalls as well: + +- Non-const enums do not fit to the conect "a typed superset of JavaScript". They violate the concept by emitting JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript. +- Const enums in contrast cannot be transpiled with Babel. But there are workarounds for this issue, e. g. using `babel-plugin-const-enum` plugin. +- To use enums you have to import them, if you want to use enum values in a template, you'll need to declare a variable in your component too. +- Numeric enums are not type safe ... + +```typescript +enum Difficulty { + EASY = 0, + NORMAL = 1, +} +const hard: Difficulty = 2; // no error +``` + +### Reasons to use Enums + +With an enum, it is much easier to find all usages of a value in a project, thus refactoring & maintaining is extremly easy. If you stick to assigning strings to the enum keys all the time, you can avoid a lot of issues. + +Another good thing is that they add meaning to otherwise meaningless values, so they can improve readability. For example `HttpStatus.Forbidden` gives more information than `Forbidden`. + +### Conclusion + +Enums are not redundant, but in most cases union is preferred. Unless you care a lot about maintainability, where Enums fit a little bit better. Here are some more interesing articles discussing this subject: + +- [Should You Use Enums or Union Types in Typescript?](https://www.bam.tech/article/should-you-use-enums-or-union-types-in-typescript) +- [Typescript has unions, so are enums redundant?](https://stackoverflow.com/questions/40275832/typescript-has-unions-so-are-enums-redundant) +- [Tidy TypeScript: Prefer union types over enums](https://fettblog.eu/tidy-typescript-avoid-enums/) + +## Statement + +The goal of this challenge is to refactor the enums `Difficulty` & `Direction` + +- Refactor `Difficulty` to const enum +- Refacotr `Direction` to union type diff --git a/docs/src/content/docs/es/index.mdx b/docs/src/content/docs/es/index.mdx index deb8340..f6b752c 100644 --- a/docs/src/content/docs/es/index.mdx +++ b/docs/src/content/docs/es/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Ir al Desafío más reciente - link: /es/challenges/angular/46-simple-animations/ + link: /es/challenges/typescript/47-enums-vs-union-types/ icon: rocket - text: Dar una estrella link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Este repositorio contiene 46 Desafíos relacionados con Angular, Nx, RxJS, Ngrx y Typescript. + + Este repositorio contiene 47 Desafíos relacionados con Angular, Nx, RxJS, Ngrx y Typescript. Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades. diff --git a/docs/src/content/docs/fr/index.mdx b/docs/src/content/docs/fr/index.mdx index d24f92a..ffd0c6e 100644 --- a/docs/src/content/docs/fr/index.mdx +++ b/docs/src/content/docs/fr/index.mdx @@ -15,7 +15,7 @@ hero: icon: right-arrow variant: primary - text: Aller au dernier Challenge - link: /fr/challenges/angular/46-simple-animations/ + link: /fr/challenges/typescript/47-enums-vs-union-types/ icon: rocket - text: Donne une étoile link: https://github.com/tomalaforge/angular-challenges @@ -28,8 +28,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Ce répertoire rassemble 46 Défis liés à Angular, Nx, RxJS, Ngrx et Typescript. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. + + Ce répertoire rassemble 47 Défis liés à Angular, Nx, RxJS, Ngrx et Typescript. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index a172533..1e1d132 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -27,8 +27,8 @@ import MyIcon from '../../components/MyIcon.astro'; import SubscriptionForm from '../../components/SubscriptionForm.astro'; - - This repository gathers 46 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. + + This repository gathers 47 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. These challenges resolve around real-life issues or specific features to elevate your skills. diff --git a/docs/src/content/docs/pt/index.mdx b/docs/src/content/docs/pt/index.mdx index 1c6de9b..068c538 100644 --- a/docs/src/content/docs/pt/index.mdx +++ b/docs/src/content/docs/pt/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Ir para o desafio mais recente - link: /pt/challenges/angular/46-simple-animations/ + link: /pt/challenges/typescript/47-enums-vs-union-types/ icon: rocket - text: Dar uma estrela link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Este repositório possui 46 Desafios relacionados a Angular, Nx, RxJS, + + Este repositório possui 47 Desafios relacionados a Angular, Nx, RxJS, Ngrx e Typescript. Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de melhorar suas habilidades. diff --git a/docs/src/content/docs/ru/index.mdx b/docs/src/content/docs/ru/index.mdx index 77b9f61..35fe566 100644 --- a/docs/src/content/docs/ru/index.mdx +++ b/docs/src/content/docs/ru/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Перейти к последней задаче - link: /ru/challenges/angular/46-simple-animations/ + link: /ru/challenges/typescript/47-enums-vs-union-types/ icon: rocket - text: Добавить звезду link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Этот репозиторий содержит 46 Испытания, связанных с Angular, Nx, RxJS, Ngrx and Typescript. + + Этот репозиторий содержит 47 Испытания, связанных с Angular, Nx, RxJS, Ngrx and Typescript. Испытания основаны на реальных задачах или инструментах для того, чтобы прокачать вас. From 80c0b78f323bc9d1bea85bd79184e2060e96f2e6 Mon Sep 17 00:00:00 2001 From: Sven Brodny Date: Thu, 29 Feb 2024 14:51:27 +0100 Subject: [PATCH 2/4] fix(challenge 47): typos --- .../typescript/47-enums-vs-union-types.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md index c214be2..bac9d26 100644 --- a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md +++ b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md @@ -26,13 +26,13 @@ On the other hand, [Union Types](https://www.typescriptlang.org/docs/handbook/2/ type Difficulty = 'EASY' | 'NORMAL'; ``` -### Reasons to use Union types +### Reasons to use Union Types -Enums are a conecpt borrowed from languages like C# and Java. TypeScript Enums are compiled into JavaScript objects with keys for both the names and values of the Enum members. This results in larger output files and additional memory consumption, which can be particularly problematic in performance-critical applications. +Enums are a concept borrowed from languages like C# and Java. TypeScript Enums are compiled into JavaScript objects with keys for both the names and values of the Enum members. This results in larger output files and additional memory consumption, which can be particularly problematic in performance-critical applications. Enums have some more pitfalls as well: -- Non-const enums do not fit to the conect "a typed superset of JavaScript". They violate the concept by emitting JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript. +- Non-const enums do not fit to the concept "a typed superset of JavaScript". They violate the concept by emitting JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript. - Const enums in contrast cannot be transpiled with Babel. But there are workarounds for this issue, e. g. using `babel-plugin-const-enum` plugin. - To use enums you have to import them, if you want to use enum values in a template, you'll need to declare a variable in your component too. - Numeric enums are not type safe ... @@ -53,7 +53,7 @@ Another good thing is that they add meaning to otherwise meaningless values, so ### Conclusion -Enums are not redundant, but in most cases union is preferred. Unless you care a lot about maintainability, where Enums fit a little bit better. Here are some more interesing articles discussing this subject: +Enums are not redundant, but in most cases union types are preferred. Unless you care a lot about maintainability, where Enums maybe fit a little bit better. Here are some more interesing articles discussing this subject: - [Should You Use Enums or Union Types in Typescript?](https://www.bam.tech/article/should-you-use-enums-or-union-types-in-typescript) - [Typescript has unions, so are enums redundant?](https://stackoverflow.com/questions/40275832/typescript-has-unions-so-are-enums-redundant) @@ -61,7 +61,7 @@ Enums are not redundant, but in most cases union is preferred. Unless you care a ## Statement -The goal of this challenge is to refactor the enums `Difficulty` & `Direction` +The goal of this challenge is to refactor the enums `Difficulty` & `Direction`. -- Refactor `Difficulty` to const enum -- Refacotr `Direction` to union type +- Refactor `Difficulty` to const enum. +- Refactor `Direction` to union type. From 8ccb746c4c4de06d4b45665f32f0eb48aec80b8e Mon Sep 17 00:00:00 2001 From: Sven Brodny Date: Sun, 3 Mar 2024 16:33:24 +0100 Subject: [PATCH 3/4] docs(enums-vs-union-types): update docs content --- .../typescript/47-enums-vs-union-types.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md index bac9d26..b918c39 100644 --- a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md +++ b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md @@ -47,9 +47,19 @@ const hard: Difficulty = 2; // no error ### Reasons to use Enums -With an enum, it is much easier to find all usages of a value in a project, thus refactoring & maintaining is extremly easy. If you stick to assigning strings to the enum keys all the time, you can avoid a lot of issues. +Enums are the best option for code refactoring, it is much easier to find all usages of a value in a project, thus refactoring & maintaining is extremly easy. If you stick to assigning strings to the enum keys all the time, you can avoid a lot of issues. -Another good thing is that they add meaning to otherwise meaningless values, so they can improve readability. For example `HttpStatus.Forbidden` gives more information than `Forbidden`. +It's true that enums produces larger output files, but that's not always a real problem. As long as the enum do it's job without any problems, it shouldn't be something you care that much about. + +Another good thing is that the necessary enum prefix add meaning to otherwise meaningless values, so they can improve readability. For example `HttpStatus.Forbidden` gives more information than `Forbidden`. + +### Mapped types + +A [mapped type](https://learntypescript.dev/08/l2-mapped-type) is the process of creating a new type by mapping type information from an existing type. + +```typescript +type Difficulty = { [K in 'EASY' | 'NORMAL']: string }; +``` ### Conclusion @@ -63,5 +73,5 @@ Enums are not redundant, but in most cases union types are preferred. Unless you The goal of this challenge is to refactor the enums `Difficulty` & `Direction`. -- Refactor `Difficulty` to const enum. -- Refactor `Direction` to union type. +- Refactor `Difficulty` enum to **union type**. +- Refactor `Direction` enum to **mapped type**. From 7918f4deb9ea613c8816fb792de7022a2b4e07a1 Mon Sep 17 00:00:00 2001 From: Sven Brodny Date: Sun, 3 Mar 2024 16:40:34 +0100 Subject: [PATCH 4/4] docs(enums-vs-union-types): update docs content (const enums) --- .../docs/challenges/typescript/47-enums-vs-union-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md index b918c39..194f689 100644 --- a/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md +++ b/docs/src/content/docs/challenges/typescript/47-enums-vs-union-types.md @@ -33,7 +33,7 @@ Enums are a concept borrowed from languages like C# and Java. TypeScript Enums a Enums have some more pitfalls as well: - Non-const enums do not fit to the concept "a typed superset of JavaScript". They violate the concept by emitting JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript. -- Const enums in contrast cannot be transpiled with Babel. But there are workarounds for this issue, e. g. using `babel-plugin-const-enum` plugin. +- Const enums in contrast cannot be transpiled with Babel. But there are workarounds for this issue, e. g. using `babel-plugin-const-enum` plugin. The TypeScript documentation about [const enums](https://www.typescriptlang.org/docs/handbook/enums.html#const-enums) says "_Do not use const enums at all_". - To use enums you have to import them, if you want to use enum values in a template, you'll need to declare a variable in your component too. - Numeric enums are not type safe ...