DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

From `const` to **Fetch**: 10 Modern TypeScript Patterns Every React Engineer Must Master

From  raw `const` endraw  to **Fetch**: 10 Modern TypeScript Patterns Every React Engineer Must Master<br>

From const to Fetch: 10 Modern TypeScript Patterns Every React Engineer Must Master

TL;DR – Whether you’re about to dive into React or leveling‑up an existing codebase, these ten “building‑block” patterns will keep your apps type‑safe, expressive, and production‑ready. We’ll walk through real .ts files (⚡ just like a lab notebook) and end with a Giphy-powered fetch demo you can copy‑paste into any React 19 project.


1 const, let, and the Death of var

// 01-const-let.ts
const firstName: string = 'Cristian';
let  diceNumber     = 6;           // can be reassigned
// var  oldSchool    = true;       // avoid: leaks to function scope
Enter fullscreen mode Exit fullscreen mode
  • constread‑only reference (not necessarily immutable data).
  • let ⇒ block‑scoped variable—use when the value must change.
  • Never use var—it hoists unpredictably and breaks module isolation.

React tip: Declare component constants (e.g. default props, route paths) at the top level with const so they’re hoisted and memo‑friendly.


2 Template Literals – No More String Math

// 02-template-string.ts
const user = 'Fer';
const repo = 42;
const uri  = `https://api.github.com/users/${user}/repos/${repo}`;
Enter fullscreen mode Exit fullscreen mode

Why you care:

  • Safer than string concatenation (typeof stays string).
  • Works inside JSX: <img alt={Avatar of ${user}} … />.

3 Object Literals + Interfaces – Talk to TypeScript

// 03-object-literal.ts
interface Hero {
  id:           string;
  displayName?: string;          // optional
  power:        string[];
}

const ironman: Hero = {
  id:    'IM-01',
  power: ['repulsor', 'AI-assistant']
};
Enter fullscreen mode Exit fullscreen mode

Why interfaces over inline types?

  • Reusable across files (export interface Hero …).
  • Extensible via declaration merging (interface Hero { suitColor: string }).
  • Automatically documented in VS Code IntelliSense.

4 Arrays & Iteration – map, filter, reduce

// 04-arrays.ts
const powers = ['speed', 'flight', 'invisibility'] as const;

const withI = powers.filter(p => p.includes('i')); // ['flight', 'invisibility']
Enter fullscreen mode Exit fullscreen mode

React tip: Pair map with stable keys in a list component:

powers.map(p => <Chip key={p} label={p} />).


5 Functions: From Simple to “Return‑Many”

// 05-functions.ts
export function rollDice(): [number, boolean] {
  const value   = Math.floor(Math.random() * 6) + 1;
  const lucky   = value === 6;
  return [value, lucky];          // tuple: number & boolean
}
Enter fullscreen mode Exit fullscreen mode
  • Return tuples when order matters ([x, y]) and destructure on call.
  • Use function overloads for variants; keep implementation private.

6 Object Destructuring – Readable Parameter Lists

// 06-obj-destructuring.ts
function printHero({ id, power }: Hero) {
  console.log(`#${id}${power.join(', ')}`);
}
Enter fullscreen mode Exit fullscreen mode

In React this shines when you pass only what’s needed:

const { power, ...rest } = hero;
<PowerMeter value={power.length} />
<HeroCard   {...rest} />
Enter fullscreen mode Exit fullscreen mode

7 Array Destructuring – Skip by Position

// 07-array-destructuring.ts
const [first, , third] = ['a', 'b', 'c']; // first='a', third='c'
Enter fullscreen mode Exit fullscreen mode

Common in hooks:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

8 Modules: import / export Without Tears

// 08-imp-exp.ts
export const AVATAR_URL = 'https://i.pravatar.cc/150?u=';
export default function avatar(id: string) {
  return `${AVATAR_URL}${id}`;
}

// elsewhere
import avatar, { AVATAR_URL } from './avatar';
Enter fullscreen mode Exit fullscreen mode

Rule of thumb:

  • One default export per file for the “main” thing.
  • Named exports for helpers & enums.

9 Promises – The Two Official Spellings

// 09-promises.ts
function dicePromise(): Promise<number> {
  return new Promise(res => {
    setTimeout(() => res(Math.floor(Math.random()*6)+1), 500);
  });
}

dicePromise().then(console.log).catch(console.error);
Enter fullscreen mode Exit fullscreen mode

Avoid the “pyramid of doom” with async/await (next section).


10 Fetch + Async/Await with the Giphy API

// 10-fetch-api.ts
interface GifResponse {
  data: { images: { downsized: { url: string } } }[];
}

export async function getRandomGif(tag: string): Promise<string> {
  const apiKey = import.meta.env.VITE_GIPHY_KEY;
  const res    = await fetch(
    `https://api.giphy.com/v1/gifs/random?api_key=${apiKey}&tag=${tag}`
  );

  if (!res.ok) throw new Error('Giphy error');
  const json = (await res.json()) as GifResponse;
  return json.data.images.downsized.url;
}
Enter fullscreen mode Exit fullscreen mode

How to use in React

import { useEffect, useState } from 'react';

export function GifCard({ tag }: { tag: string }) {
  const [url, setUrl] = useState<string>();

  useEffect(() => {
    getRandomGif(tag).then(setUrl).catch(console.error);
  }, [tag]);

  return url ? <img src={url} alt={tag} /> : <p>Loading...</p>;
}
Enter fullscreen mode Exit fullscreen mode
  • Type the promise return so consumers get autocomplete for image URLs.
  • Pull your API key from Vite environment variables (VITE_*).

Cheat‑Sheet: Which Tool for Which Problem?

Need Use
Immutable references const
Mutable loop index let
Multi-line interpolation Template literals
Shared shape across files interface
Map over data in JSX array.map
Multiple values back Tuple returns
Reusable stateful logic Custom React hook
Async HTTP fetch + async/await
Compile‑time constants enum or as const array

Final Thoughts

Great React apps aren’t built with components alone—they’re forged from thousands of tiny language habits that compound:

  • Choosing the right declaration (const vs let) keeps state predictable.
  • Typing objects and return values unlocks IntelliSense and refactor‑proofing.
  • Mastering fetch with proper response interfaces prevents runtime 500s.

Commit these patterns to muscle memory before you dive into higher‑order hooks, state machines, or fancy animation libraries, and you’ll code like a scientific React‑TypeScript meta‑engineer every single day.

Happy hacking—and may your API calls always resolve! 🚀

✍️ Written by: Cristian Sifuentes – Full-stack dev crafting scalable apps with [NET - Azure], [Angular - React], Git, SQL & extensions. Clean code, dark themes, atomic commits


Tags: react19, typescript, javascript, async-await, state-management, frontend

Top comments (0)