diff --git a/404.html b/404.html index 9473474..ecb5d6d 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@
// Array constant
type UserRole = 'admin' | 'editor' | 'moderator' | 'viewer' | 'guest';
// ❌ Avoid constant of wide type
const DASHBOARD_ACCESS_ROLES: ReadonlyArray<UserRole> = ['admin', 'editor', 'moderator'];
// ❌ Avoid constant with incorrect values
const DASHBOARD_ACCESS_ROLES = ['admin', 'contributor', 'analyst'] as const;
// ✅ Use immutable constant of narrowed type
const DASHBOARD_ACCESS_ROLES = ['admin', 'editor', 'moderator'] as const satisfies ReadonlyArray<UserRole>;
// Object constant
type OrderStatus = {
pending: 'pending' | 'idle';
fulfilled: boolean;
error: string;
};
// ❌ Avoid mutable constant of wide type
const IDLE_ORDER: OrderStatus = {
pending: 'idle',
fulfilled: true,
error: 'Shipping Error',
};
// ❌ Avoid constant with incorrect values
const IDLE_ORDER = {
pending: 'done',
fulfilled: 'partially',
error: 116,
} as const;
// ✅ Use immutable constant of narrowed type
const IDLE_ORDER = {
pending: 'idle',
fulfilled: true,
error: 'Shipping Error',
} as const satisfies OrderStatus;
Template literal types allow you to create precise and type-safe string constructs by interpolating values. They are a powerful alternative to using the wide string type, providing better type safety and developer experience.
-Adopting template literal types brings several advantages::
+Adopting template literal types brings several advantages:
// ❌ Avoid
import { bar, foo } from '../../../../../../distant-folder';
// ✅ Use
import { locationApi } from '@api/locationApi';
import { foo } from '../../foo';
import { bar } from '../bar';
import { baz } from './baz';
Example frontend monorepo project, where every application has file/folder grouped by feature:
-apps/
├─ product-manager/
│ ├─ common/
│ │ ├─ components/
│ │ │ ├─ Button/
│ │ │ ├─ ProductTitle/
│ │ │ ├─ ...
│ │ │ └─ index.tsx
│ │ ├─ consts/
│ │ │ ├─ paths.ts
│ │ │ └─ ...
│ │ ├─ hooks/
│ │ └─ types/
│ ├─ modules/
│ │ ├─ HomePage/
│ │ ├─ ProductAddPage/
│ │ ├─ ProductPage/
│ │ ├─ ProductsPage/
│ │ │ ├─ api/
│ │ │ │ └─ useGetProducts/
│ │ │ ├─ components/
│ │ │ │ ├─ ProductItem/
│ │ │ │ ├─ ProductsStatistics/
│ │ │ │ └─ ...
│ │ │ ├─ utils/
│ │ │ │ └─ filterProductsByType/
│ │ │ └─ index.tsx
│ │ ├─ ...
│ │ └─ index.tsx
│ ├─ eslintrc.js
│ ├─ package.json
│ └─ tsconfig.json
├─ warehouse/
├─ admin-dashboard/
└─ ...
apps/
├─ product-manager/
│ ├─ common/
│ │ ├─ components/
│ │ │ ├─ Button/
│ │ │ ├─ ProductTitle/
│ │ │ ├─ ...
│ │ │ └─ index.tsx
│ │ ├─ consts/
│ │ │ ├─ paths.ts
│ │ │ └─ ...
│ │ ├─ hooks/
│ │ └─ types/
│ ├─ modules/
│ │ ├─ HomePage/
│ │ ├─ ProductAddPage/
│ │ ├─ ProductPage/
│ │ ├─ ProductsPage/
│ │ │ ├─ api/
│ │ │ │ └─ useGetProducts/
│ │ │ ├─ components/
│ │ │ │ ├─ ProductItem/
│ │ │ │ ├─ ProductsStatistics/
│ │ │ │ └─ ...
│ │ │ ├─ utils/
│ │ │ │ └─ filterProductsByType/
│ │ │ └─ index.tsx
│ │ ├─ ...
│ │ └─ index.tsx
│ ├─ eslintrc.js
│ ├─ package.json
│ └─ tsconfig.json
├─ warehouse/
├─ admin-dashboard/
└─ ...
modules
folder is responsible for implementation of each individual page, where all custom features for that page are being implemented (components, hooks, utils functions etc.).common
folder is responsible for implementations that are truly used across application. Since it's a "global folder" it should be used sparingly.