mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 12:53:03 -05:00
Merge pull request #638 from svenson95/add-challenge-typescript-enums-vs-union-types
feat(challenge 47): typescript enums vs union types
This commit is contained in:
@@ -24,7 +24,7 @@ If you would like to propose a challenge, this project is open source, so feel f
|
|||||||
|
|
||||||
## Challenges
|
## Challenges
|
||||||
|
|
||||||
Check [all 46 challenges](https://angular-challenges.vercel.app/)
|
Check [all 47 challenges](https://angular-challenges.vercel.app/)
|
||||||
|
|
||||||
## Contributors ✨
|
## Contributors ✨
|
||||||
|
|
||||||
|
|||||||
36
apps/typescript/enums-vs-union-types/.eslintrc.json
Normal file
36
apps/typescript/enums-vs-union-types/.eslintrc.json
Normal file
@@ -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": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
13
apps/typescript/enums-vs-union-types/README.md
Normal file
13
apps/typescript/enums-vs-union-types/README.md
Normal file
@@ -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/).
|
||||||
73
apps/typescript/enums-vs-union-types/project.json
Normal file
73
apps/typescript/enums-vs-union-types/project.json
Normal file
@@ -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}"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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: `
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<button mat-stroked-button (click)="difficulty.set(Difficulty.EASY)">
|
||||||
|
Easy
|
||||||
|
</button>
|
||||||
|
<button mat-stroked-button (click)="difficulty.set(Difficulty.NORMAL)">
|
||||||
|
Normal
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p>Selected Difficulty: {{ difficultyLabel() }}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div>
|
||||||
|
<button mat-stroked-button (click)="direction.set(Direction.LEFT)">
|
||||||
|
Left
|
||||||
|
</button>
|
||||||
|
<button mat-stroked-button (click)="direction.set(Direction.RIGHT)">
|
||||||
|
Right
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p>{{ directionLabel() }}</p>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
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>(Difficulty.EASY);
|
||||||
|
|
||||||
|
readonly Direction = Direction;
|
||||||
|
readonly direction = signal<Direction | undefined>(undefined);
|
||||||
|
|
||||||
|
readonly difficultyLabel = computed<string>(() => {
|
||||||
|
switch (this.difficulty()) {
|
||||||
|
case Difficulty.EASY:
|
||||||
|
return Difficulty.EASY;
|
||||||
|
case Difficulty.NORMAL:
|
||||||
|
return Difficulty.NORMAL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
readonly directionLabel = computed<string>(() => {
|
||||||
|
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!';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { ApplicationConfig } from '@angular/core';
|
||||||
|
|
||||||
|
export const appConfig: ApplicationConfig = {
|
||||||
|
providers: [],
|
||||||
|
};
|
||||||
BIN
apps/typescript/enums-vs-union-types/src/favicon.ico
Normal file
BIN
apps/typescript/enums-vs-union-types/src/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
13
apps/typescript/enums-vs-union-types/src/index.html
Normal file
13
apps/typescript/enums-vs-union-types/src/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>typescript-enums-vs-union-types</title>
|
||||||
|
<base href="/" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
7
apps/typescript/enums-vs-union-types/src/main.ts
Normal file
7
apps/typescript/enums-vs-union-types/src/main.ts
Normal file
@@ -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),
|
||||||
|
);
|
||||||
5
apps/typescript/enums-vs-union-types/src/styles.scss
Normal file
5
apps/typescript/enums-vs-union-types/src/styles.scss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
14
apps/typescript/enums-vs-union-types/tailwind.config.js
Normal file
14
apps/typescript/enums-vs-union-types/tailwind.config.js
Normal file
@@ -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: [],
|
||||||
|
};
|
||||||
10
apps/typescript/enums-vs-union-types/tsconfig.app.json
Normal file
10
apps/typescript/enums-vs-union-types/tsconfig.app.json
Normal file
@@ -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"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"include": ["src/**/*.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": []
|
||||||
|
}
|
||||||
|
}
|
||||||
30
apps/typescript/enums-vs-union-types/tsconfig.json
Normal file
30
apps/typescript/enums-vs-union-types/tsconfig.json
Normal file
@@ -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,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"total": 46,
|
"total": 47,
|
||||||
"🟢": 17,
|
"🟢": 18,
|
||||||
"🟠": 120,
|
"🟠": 120,
|
||||||
"🔴": 209
|
"🔴": 209
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ challengeNumber: 46
|
|||||||
command: angular-simple-animations
|
command: angular-simple-animations
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 17
|
order: 17
|
||||||
badge: New
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Information
|
## Information
|
||||||
@@ -45,4 +44,3 @@ Add a stagger animation for the list on the right side.
|
|||||||
|
|
||||||
<video controls src="https://github.com/svenson95/angular-challenges/assets/46655156/7b5e770f-38bb-43a2-9dd1-cc1329cab82f">
|
<video controls src="https://github.com/svenson95/angular-challenges/assets/46655156/7b5e770f-38bb-43a2-9dd1-cc1329cab82f">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
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 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 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. 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 ...
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
enum Difficulty {
|
||||||
|
EASY = 0,
|
||||||
|
NORMAL = 1,
|
||||||
|
}
|
||||||
|
const hard: Difficulty = 2; // no error
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reasons to use Enums
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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)
|
||||||
|
- [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` enum to **union type**.
|
||||||
|
- Refactor `Direction` enum to **mapped type**.
|
||||||
@@ -13,7 +13,7 @@ hero:
|
|||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
variant: primary
|
variant: primary
|
||||||
- text: Ir al Desafío más reciente
|
- 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
|
icon: rocket
|
||||||
- text: Dar una estrella
|
- text: Dar una estrella
|
||||||
link: https://github.com/tomalaforge/angular-challenges
|
link: https://github.com/tomalaforge/angular-challenges
|
||||||
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
|
|||||||
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
||||||
|
|
||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="46 Desafíos">
|
<Card title="47 Desafíos">
|
||||||
Este repositorio contiene 46 Desafíos relacionados con <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> y <b>Typescript</b>.
|
Este repositorio contiene 47 Desafíos relacionados con <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> y <b>Typescript</b>.
|
||||||
Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades.
|
Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades.
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ hero:
|
|||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
variant: primary
|
variant: primary
|
||||||
- text: Aller au dernier Challenge
|
- text: Aller au dernier Challenge
|
||||||
link: /fr/challenges/angular/46-simple-animations/
|
link: /fr/challenges/typescript/47-enums-vs-union-types/
|
||||||
icon: rocket
|
icon: rocket
|
||||||
- text: Donne une étoile
|
- text: Donne une étoile
|
||||||
link: https://github.com/tomalaforge/angular-challenges
|
link: https://github.com/tomalaforge/angular-challenges
|
||||||
@@ -28,8 +28,8 @@ import MyIcon from '../../../components/MyIcon.astro';
|
|||||||
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
||||||
|
|
||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="46 Défis">
|
<Card title="47 Défis">
|
||||||
Ce répertoire rassemble 46 Défis liés à <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> et <b>Typescript</b>. 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 à <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> et <b>Typescript</b>. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences.
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card title="Subscribe to get notify of latest challenges">
|
<Card title="Subscribe to get notify of latest challenges">
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import MyIcon from '../../components/MyIcon.astro';
|
|||||||
import SubscriptionForm from '../../components/SubscriptionForm.astro';
|
import SubscriptionForm from '../../components/SubscriptionForm.astro';
|
||||||
|
|
||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="46 Challenges">
|
<Card title="47 Challenges">
|
||||||
This repository gathers 46 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.
|
This repository gathers 47 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.
|
||||||
These challenges resolve around real-life issues or specific features to elevate your skills.
|
These challenges resolve around real-life issues or specific features to elevate your skills.
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ hero:
|
|||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
variant: primary
|
variant: primary
|
||||||
- text: Ir para o desafio mais recente
|
- 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
|
icon: rocket
|
||||||
- text: Dar uma estrela
|
- text: Dar uma estrela
|
||||||
link: https://github.com/tomalaforge/angular-challenges
|
link: https://github.com/tomalaforge/angular-challenges
|
||||||
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
|
|||||||
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
||||||
|
|
||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="46 Desafios">
|
<Card title="47 Desafios">
|
||||||
Este repositório possui 46 Desafios relacionados a <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>,
|
Este repositório possui 47 Desafios relacionados a <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>,
|
||||||
<b>Ngrx</b> e <b>Typescript</b>.
|
<b>Ngrx</b> e <b>Typescript</b>.
|
||||||
Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de
|
Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de
|
||||||
melhorar suas habilidades.
|
melhorar suas habilidades.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ hero:
|
|||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
variant: primary
|
variant: primary
|
||||||
- text: Перейти к последней задаче
|
- text: Перейти к последней задаче
|
||||||
link: /ru/challenges/angular/46-simple-animations/
|
link: /ru/challenges/typescript/47-enums-vs-union-types/
|
||||||
icon: rocket
|
icon: rocket
|
||||||
- text: Добавить звезду
|
- text: Добавить звезду
|
||||||
link: https://github.com/tomalaforge/angular-challenges
|
link: https://github.com/tomalaforge/angular-challenges
|
||||||
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
|
|||||||
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
import SubscriptionForm from '../../../components/SubscriptionForm.astro';
|
||||||
|
|
||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="46 Испытания">
|
<Card title="47 Испытания">
|
||||||
Этот репозиторий содержит 46 Испытания, связанных с <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.
|
Этот репозиторий содержит 47 Испытания, связанных с <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.
|
||||||
Испытания основаны на реальных задачах или инструментах для того, чтобы прокачать вас.
|
Испытания основаны на реальных задачах или инструментах для того, чтобы прокачать вас.
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user