Skip to content

Commit 280f562

Browse files
committed
enhance exercises: add examples for promises, async/await, modules, and utility types with type annotations and error handling
1 parent 33972cd commit 280f562

16 files changed

Lines changed: 179 additions & 9 deletions

File tree

exercises/01.promises/01.problem.creation/README.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
👨‍💼 We need to simulate an API call that fetches user data. Let's create a
44
Promise that resolves with user information after a delay.
55

6+
```ts
7+
type Forecast = { day: string; high: number }
8+
9+
const fetchForecast = () =>
10+
new Promise<Forecast>((resolve) => {
11+
setTimeout(() => resolve({ day: 'Mon', high: 72 }), 500)
12+
})
13+
```
14+
615
🐨 Open <InlineFile file="index.ts" /> and:
716

817
1. Create a `fetchUser` function that returns a `Promise<User>`

exercises/01.promises/02.problem.chaining/README.mdx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
👨‍💼 After fetching a user, we need to fetch their orders. Let's chain these
44
operations together using `.then()`.
55

6+
```ts
7+
type Playlist = { id: string; name: string }
8+
type Track = { id: string; title: string }
9+
10+
function fetchPlaylist(): Promise<Playlist> {
11+
return Promise.resolve({ id: 'pl1', name: 'Morning Mix' })
12+
}
13+
14+
function fetchTracks(playlistId: string): Promise<Array<Track>> {
15+
return Promise.resolve([{ id: `${playlistId}-t1`, title: 'Sunrise' }])
16+
}
17+
18+
fetchPlaylist()
19+
.then((playlist) => fetchTracks(playlist.id))
20+
.then((tracks) => console.log(tracks))
21+
```
22+
623
🐨 Open <InlineFile file="index.ts" /> and:
724

825
1. Implement `fetchUser` and `fetchOrders` so they resolve with data

exercises/02.async-await/01.problem.linear-flow/README.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@
33
👨‍💼 Let's convert the Promise chain from the previous exercise to use
44
async/await. This will make the code much more readable!
55

6+
```ts
7+
type Recipe = { id: string; title: string }
8+
type Ingredient = { name: string }
9+
10+
async function loadRecipe(id: string): Promise<Recipe> {
11+
return { id, title: 'Pancakes' }
12+
}
13+
14+
async function loadIngredients(recipeId: string): Promise<Array<Ingredient>> {
15+
return [{ name: `${recipeId}-flour` }]
16+
}
17+
18+
async function loadCookingData() {
19+
const recipe = await loadRecipe('r1')
20+
const ingredients = await loadIngredients(recipe.id)
21+
return { recipe, ingredients }
22+
}
23+
```
24+
625
🐨 Open <InlineFile file="index.ts" /> and:
726

827
1. Create an `async` function called `loadUserData`

exercises/02.async-await/02.problem.error-handling/README.mdx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@
33
👨‍💼 Our async code needs proper error handling. Let's use try/catch to handle
44
failures gracefully.
55

6+
```ts
7+
async function readConfig() {
8+
if (Math.random() > 0.5) throw new Error('Missing config')
9+
return { theme: 'dark' }
10+
}
11+
12+
async function loadSettings() {
13+
try {
14+
const config = await readConfig()
15+
return config
16+
} catch (error) {
17+
return { theme: 'light', error }
18+
} finally {
19+
// cleanup
20+
}
21+
}
22+
```
23+
624
🐨 Open <InlineFile file="index.ts" /> and:
725

826
1. Wrap the async operations in a `try` block

exercises/02.async-await/03.problem.promise-types/README.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
👨‍💼 Let's ensure our async functions have proper type annotations. This helps
44
TypeScript catch errors and makes our code more maintainable.
55

6+
```ts
7+
type Episode = { id: string; title: string }
8+
9+
async function fetchEpisode(): Promise<Episode> {
10+
return { id: 'e1', title: 'Pilot' }
11+
}
12+
13+
async function fetchEpisodeIds(): Promise<Array<string>> {
14+
return ['e1', 'e2']
15+
}
16+
```
17+
618
🐨 Open <InlineFile file="index.ts" /> and:
719

820
1. Add explicit return type annotations to all async functions

exercises/03.modules/01.problem.import-export/README.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
👨‍💼 Our code is getting large. Let's split it into separate modules to keep
44
things organized.
55

6+
```ts
7+
// types.ts
8+
export type Book = { title: string; pages: number }
9+
10+
// index.ts
11+
import { type Book } from './types.ts'
12+
```
13+
614
🐨 Create a new file `types.ts` and:
715

816
1. Move the `User` and `Product` types to `types.ts`

exercises/03.modules/02.problem.default-vs-named/README.mdx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
👨‍💼 There are two ways to export from modules: named exports and default
44
exports. Let's understand when to use each.
55

6+
```ts
7+
// utils.ts
8+
export function formatDistance(meters: number) {
9+
return `${meters}m`
10+
}
11+
12+
export function formatDuration(seconds: number) {
13+
return `${seconds}s`
14+
}
15+
16+
export default class UnitFormatter {
17+
formatDistance(meters: number) {
18+
return formatDistance(meters)
19+
}
20+
}
21+
```
22+
623
🐨 Open <InlineFile file="utils.ts" /> and:
724

825
1. Export `formatCurrency` as a **named export**

exercises/04.type-operators/01.problem.keyof-typeof/README.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
👨‍💼 Let's use `keyof` and `typeof` to create type-safe utilities.
44

5+
```ts
6+
const palette = {
7+
primary: '#222222',
8+
accent: '#ff6600',
9+
}
10+
11+
type PaletteKey = keyof typeof palette
12+
13+
const sizes = ['sm', 'md', 'lg'] as const
14+
type Size = (typeof sizes)[number]
15+
```
16+
517
🐨 Open <InlineFile file="index.ts" /> and:
618
719
1. Use `keyof` to get the keys of an object type

exercises/04.type-operators/02.problem.index-access/README.mdx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
bracket notation.
55

66
```ts
7-
type User = { id: string; name: string; settings: { theme: 'light' | 'dark' } }
7+
type Recipe = {
8+
title: string
9+
author: { name: string; rating: 1 | 2 | 3 | 4 | 5 }
10+
}
811

9-
type IdType = User['id'] // string
10-
type SettingsType = User['settings'] // { theme: 'light' | 'dark' }
11-
type ThemeType = User['settings']['theme'] // 'light' | 'dark'
12+
type TitleType = Recipe['title'] // string
13+
type AuthorType = Recipe['author'] // { name: string; rating: 1 | 2 | 3 | 4 | 5 }
14+
type RatingType = Recipe['author']['rating'] // 1 | 2 | 3 | 4 | 5
1215
```
1316
1417
🐨 Open <InlineFile file="index.ts" /> and:

exercises/05.utility-types/01.problem.partial-pick/README.mdx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
👨‍💼 We need to create types for updating user data. Some fields should be
44
optional, and we only want to allow updating specific fields.
55

6+
```ts
7+
type Article = {
8+
id: string
9+
title: string
10+
body: string
11+
updatedAt: Date
12+
}
13+
14+
type ArticlePatch = Partial<Pick<Article, 'title' | 'body'>>
15+
```
16+
617
🐨 Open <InlineFile file="index.ts" /> and:
718
819
1. Use `Partial<User>` to create a type where all properties are optional

0 commit comments

Comments
 (0)