Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const Enums = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Enums</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
Enums define a set of named constants. Prefer <strong>union string literals</strong> for
most cases, but enums can be helpful when interoperating with existing code or when you
need reverse mapping.
</p>

<CodeBlock
code={`// Numeric enum
enum Direction {
Up = 1,
Down,
Left,
Right
}

const d: Direction = Direction.Up;

// String enum
enum Role {
Admin = 'admin',
User = 'user',
Guest = 'guest'
}

function canEdit(role: Role) {
return role === Role.Admin;
}`}
/>

<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mt-8 mb-4">Alternatives</h2>

<CodeBlock
code={`// Prefer unions for type safety and tree-shaking
type Role = 'admin' | 'user' | 'guest';
const canEdit = (role: Role) => role === 'admin';`}
/>
</div>
</div>
);
};

export default Enums;


Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const Generics = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Generics</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
Generics enable reusable components that work with a variety of types while maintaining
type safety.
</p>

<CodeBlock
code={`// Generic identity
function identity<T>(value: T): T {
return value;
}

const n = identity<number>(42);
const s = identity('hello'); // type inferred

// Generic interfaces
interface ApiResponse<T> {
data: T;
status: number;
}

type User = { id: number; name: string };
const res: ApiResponse<User> = { data: { id: 1, name: 'Alex' }, status: 200 };`}
/>

<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mt-8 mb-4">Constraints</h2>

<CodeBlock
code={`// Constraining generic parameters
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}

const user = { id: 1, name: 'Alex' };
const name = getProp(user, 'name'); // type: string`}
/>
</div>
</div>
);
};

export default Generics;


Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const IntersectionTypes = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Intersection Types</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
Intersection types combine multiple types into one using the <code>&</code> operator. The
resulting type must satisfy all members.
</p>

<CodeBlock
code={`type HasId = { id: string };
type Timestamped = { createdAt: Date; updatedAt: Date };
type Entity = HasId & Timestamped;

const user: Entity = {
id: 'u_1',
createdAt: new Date(),
updatedAt: new Date()
};`}
/>

<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mt-8 mb-4">With Interfaces</h2>

<CodeBlock
code={`interface Named { name: string }
interface Aged { age: number }
type Person = Named & Aged;

const p: Person = { name: 'Alex', age: 30 };`}
/>
</div>
</div>
);
};

export default IntersectionTypes;


Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const LiteralTypes = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Literal Types</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
Literal types restrict a value to a specific string, number, or boolean.
Combine them with unions to model finite sets.
</p>

<CodeBlock
code={`let direction: 'up' | 'down' | 'left' | 'right' = 'up';

type HttpStatus = 200 | 400 | 404 | 500;
let status: HttpStatus = 200;

// Discriminated unions with literals
type Square = { kind: 'square'; size: number };
type Circle = { kind: 'circle'; radius: number };
type Shape = Square | Circle;`}
/>
</div>
</div>
);
};

export default LiteralTypes;


Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const UnionTypes = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Union Types</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
Union types let a value be one of several types using the <code>|</code> operator. They are
ideal when an API accepts a limited set of primitives or shapes.
</p>

<CodeBlock
code={`// Basic unions
let id: string | number;
id = 'abc123';
id = 42;

// Function parameters with unions
function formatId(id: string | number): string {
return typeof id === 'string' ? id.toUpperCase() : id.toString();
}

// Narrowing with typeof
function toFixedIfNumber(value: string | number) {
if (typeof value === 'number') {
return value.toFixed(2);
}
return value;
}`}
/>

<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mt-8 mb-4">Unions with Objects</h2>

<CodeBlock
code={`type Success = { status: 'success'; data: string };
type Failure = { status: 'error'; message: string };
type Result = Success | Failure;

function handle(result: Result) {
if (result.status === 'success') {
return result.data; // narrowed to Success
}
return result.message; // narrowed to Failure
}`}
/>
</div>
</div>
);
};

export default UnionTypes;


Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import CodeBlock from '../../../components/CodeBlock';

const UtilityTypes = () => {
return (
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg dark:prose-invert max-w-none">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Utility Types</h1>

<p className="text-gray-700 dark:text-gray-300 mb-4">
TypeScript includes built-in utility types that transform existing types to help with
common tasks like making properties optional, required, or read-only.
</p>

<CodeBlock
code={`type User = { id: number; name: string; email?: string };

// Partial: make all props optional
type UserDraft = Partial<User>;

// Required: make all props required
type UserRequired = Required<User>;

// Readonly: make all props readonly
type UserReadonly = Readonly<User>;

// Pick / Omit
type UserPublic = Pick<User, 'id' | 'name'>;
type UserPrivate = Omit<User, 'email'>;

// Record
type UsersById = Record<number, UserPublic>;`}
/>

<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mt-8 mb-4">NonNullable & ReturnType</h2>

<CodeBlock
code={`type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string

function makeUser(name: string) {
return { id: 1, name };
}
type MakeUserReturn = ReturnType<typeof makeUser>;`}
/>
</div>
</div>
);
};

export default UtilityTypes;


Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ import TypeInference from './TsTopics/TsBasics/TypeInference';
import TypeAssertions from './TsTopics/TsBasics/TypeAssertions';

// Advanced Types
// import UnionTypes from './TsTopics/AdvancedTypes/UnionTypes';
// import IntersectionTypes from './TsTopics/AdvancedTypes/IntersectionTypes';
// import LiteralTypes from './TsTopics/AdvancedTypes/LiteralTypes';
// import Enums from './TsTopics/AdvancedTypes/Enums';
// import Generics from './TsTopics/AdvancedTypes/Generics';
// import UtilityTypes from './TsTopics/AdvancedTypes/UtilityTypes';
import UnionTypes from './TsTopics/AdvancedTypes/UnionTypes';
import IntersectionTypes from './TsTopics/AdvancedTypes/IntersectionTypes';
import LiteralTypes from './TsTopics/AdvancedTypes/LiteralTypes';
import Enums from './TsTopics/AdvancedTypes/Enums';
import Generics from './TsTopics/AdvancedTypes/Generics';
import UtilityTypes from './TsTopics/AdvancedTypes/UtilityTypes';

// Functions and Classes
// import FunctionTypes from './TsTopics/FunctionsClasses/FunctionTypes';
Expand Down Expand Up @@ -118,13 +118,13 @@ const TypeScriptEssentials = () => {
<Route path="type-inference" element={<TypeInference />} />
<Route path="type-assertions" element={<TypeAssertions />} />

{/* Advanced Types - Will be added in PR #4 */}
{/* <Route path="union-types" element={<UnionTypes />} />
{/* Advanced Types */}
<Route path="union-types" element={<UnionTypes />} />
<Route path="intersection-types" element={<IntersectionTypes />} />
<Route path="literal-types" element={<LiteralTypes />} />
<Route path="enums" element={<Enums />} />
<Route path="generics" element={<Generics />} />
<Route path="utility-types" element={<UtilityTypes />} /> */}
<Route path="utility-types" element={<UtilityTypes />} />

{/* Functions and Classes - Will be added in PR #5 */}
{/* <Route path="function-types" element={<FunctionTypes />} />
Expand Down