Sign in

Cory House

@housecor.com
2.2K followers 61 following 136 posts

Courses: pluralsight.com YouTube: youtube.com/@housecor Consulting: reactjsconsulting.com ⚛️

PostsRepliesMedia
Cory House @housecor.com · 02/06/2025
TypeScript syntax is often inspired by JavaScript. In some cases, TS even uses the exact same syntax as JS for a different purpose. The difference? JS features focus on values. TS features focus on types. Here's a few examples.
040
Cory House @housecor.com · 29/05/2025
Problem: I want to enforce a string format at compile time. Solution: Use a template literal type. Full "TypeScript: Deep Dive" course: dometrain.com/course/deep-...
000
Cory House @housecor.com · 28/05/2025
Problem: I want to ensure my switch statement handles all potential cases. Solution: Use TypeScript's never type. Here's how: Full course: dometrain.com/course/deep-...
040
Cory House @housecor.com · 24/05/2025
Problem: You have complex logic for narrowing a TypeScript type that you'd like to reuse in a few spots. Solution: Consider an assertion function. 20% off the full course: dometrain.com/course/deep-...
150
Cory House @housecor.com · 23/05/2025
It’s live! “TypeScript: Deep Dive” explores advanced TS concepts: - Utility types - Generics - Mapped types - Conditional types - Template literal types - Runtime validation - Decorators - tsconfig techniques And over 250+ examples! Get 20% off at launch here: dometrain.com/course/deep-...
061
Cory House @housecor.com · 22/05/2025
LLMs are handy when working with the command line. I wanted a count of all the exercise files in my new course. ChatGPT provided the correct Bash command immediately.
240
Cory House @housecor.com · 13/05/2025
Just realized Vitest now has built in support for testing TypeScript types. How? It includes expect-type now by default. Handy. Example:
import { assertType, expectTypeOf } from 'vitest'
import { mount } from './mount.js'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()  

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }))
})
171
Cory House @housecor.com · 13/04/2025
There are many JS runtimes - Node, Deno, Bun, etc. Just learned about a new one: Bare. Bare is unique: - Light (runs on mobile) - No server (great for P2P apps) - Not tied to a specific JS engine. - Separate modules (Upgrade modules when desired. Install what you need) More: bare.pears.com
0101
Cory House @housecor.com · 28/03/2025
I've heard people say "spelling mistakes in code are harmless". I disagree. Spelling mistakes slow reading, create confusion, and can lead to bugs. Solution: Run cspell as part of your CI process. Here's an example cspell just found - a misspelled style that wasn't applying.
<Box sx={{ alignItems: 'cenetr' }}>
371
Cory House @housecor.com · 25/03/2025
Problem: Unused npm dependencies. They make package.json harder to read, bloat node_modules, waste our time updating packages we don’t use, and create confusion about what our project requires. Solution: npx depcheck It lists unused dependencies.
2120
Cory House @housecor.com · 21/03/2025
Problem: I want to see a list of the settings I've changed in VS Code. Solution: Search for @modified. This displays a list of modified settings. I used this today because I recently changed a setting that I wanted to revert, and couldn't recall the setting's name.
1152
Cory House @housecor.com · 18/03/2025
Now that Node, Bun, and Deno can run TS files directly without compilation, using JSDoc syntax to declare TypeScript types is even harder to justify. JSDoc syntax is more verbose, lacks full feature support, and is harder to read. Look at this comparison. Easy choice.
// Prefer this
type User = {
  /** User's ID */
  id: number, 
  
  /** User's name. */
  name: string
};

// Over this:
/**
 * @typedef {Object} User
 * @property {number} id - User's ID.
 * @property {string} name - User's name.
 */
2120
Cory House @housecor.com · 14/03/2025
Learn TypeScript in 60 seconds.
0120
Cory House @housecor.com · 11/03/2025
I think I finally have my phone-friendly vertical video format dialed in. I'm using an iPad with a Neewer teleprompter as my monitor so I can look directly at the code as I narrate. And Camtasia creates the slick captions. Thoughts?
160
Cory House @housecor.com · 11/03/2025
In TypeScript, interfaces and type aliases can "extend" each another. - An interface can extend a type. - A type alias can "extend" an interface (via a type intersection). Clip from "TypeScript: Getting Started" on Dometrain: dometrain.com/course/getti...
281
Cory House @housecor.com · 09/03/2025
Just submitted the final clips for "TypeScript: Getting Started". 🎉 The course explores primitive types, arrays, tuples, enums, interfaces, functions, classes, modules, using TS with and without a compiler, features to avoid, and much more. Publishing this week on Dometrain!
0150
Cory House @housecor.com · 01/01/2025
V0's system prompt specifies these naming and casing rules. I agree with all this. For years, I used PascalCase for React components. But I now I use kebab-case instead to avoid casing issues.
1. File Naming Conventions:
- MUST use kebab-case for ALL file names
CORRECT: user-profile.tsx, auth-layout.tsx, api-utils.ts
INCORRECT: userProfile.tsx, AuthLayout.tsx, apiUtils.ts
- MUST use .tsx extension for React components
- MUST use .ts extension for utility files
- MUST use lowercase for all file names
- MUST separate words with hyphens
- MUST NOT use spaces or underscores
5160
Cory House @housecor.com · 02/12/2024
I used to use Google and use Stackoverflow. Now I ask ChatGPT. It summarizes complex decisions quickly and lays out the information in a helpful manner. For example, I am considering a GUID primary key. ChatGPT summarizes the tradeoffs nicely.
3110
Cory House @housecor.com · 25/11/2024
Next.js and React Router 7 (RR7) have fundamentally different approaches to decomposition. In Next.js, you decompose via files. In React Router 7, you decompose via functions. Which do you prefer, and why?
8120
Cory House @housecor.com · 15/11/2024
Sure!
const config = {
  entry: ["src/main.tsx"],
  ignore: [
    // Deliberately telling Knip to ignore all test files. 
    // This way, if a file or func is only used by a test, knip will report it as unused. 
    "src/**/*.test.*",
  ]
}
130
Cory House @housecor.com · 15/11/2024
React 19 RC1 is out. Suspense siblings prerender! When a component suspends, React commits the fallback of the nearest Suspense boundary without waiting for the sibling tree to render. Then it schedules another render for the siblings. Details: github.com/facebook/rea...
1304
Cory House @housecor.com · 08/11/2024
Problem: I want to test my React app's error boundaries. Solution: Force an error via search params. This hook throws an error when a "throwError" search param is present. I use this to test my ErrorBoundaries in my automated tests too.
function useForceErrorViaSearchParam() {
  const [searchParams] = useSearchParams();
  const error = searchParams.get("throwError"); 
  if (error) throw new Error(error);
}
2131
Cory House @housecor.com · 07/11/2024
Just published: Mastering Mocking in Automated Tests I talk with @kettanaito.com about best practices for writing mocks including mocking mistakes, finding mocking boundaries, mock data, distinctions between different types of testing, and much more.
181
Cory House @housecor.com · 06/11/2024
Tanstack query is awesome for fetching and caching data. But, it's broader than that. It's an *async state* library. Example: Here's a custom React Query hook for checking if a device's camera or audio input is available.
import { useQuery } from "@tanstack/react-query";

type Status = "loading" | "error fetching" | "no devices found" | "available";

export const useMediaAvailability = (kind: MediaDeviceKind) =>
  useQuery({
    queryKey: ["mediaAvailability", kind],
    queryFn: async (): Promise<Status> => {
      try {
        const mediaDevices = await navigator.mediaDevices.enumerateDevices();
        const cameraDevices = mediaDevices.filter((device) => device.kind === kind);  
        if (cameraDevices.length && cameraDevices.some((d) => d.label)) {
          return "available";
        }
        return "no devices found";
      } catch (error) {
        return "error fetching";
      }
    },
  });
0231
Cory House @housecor.com · 06/11/2024
Studio setup 2.0: - Closed blinds (to control the light) - New 5600K keylight & backlight - Camera white balance at 5600K - New camera angle (hides door) - Recording in 4K/24p at 1/50 - Cleaner background - Added accent lights - Brushed my hair Thoughts? Suggestions?
5100
Cory House @housecor.com · 05/11/2024
Mistake: Needlessly wide optional field. What's the semantic difference between an omitted address property, a null address, an undefined address, and an address that has no properties? 😬 Solution: Narrow the field's type. The address is either populated or null.

// Avoid. Needlessly wide. 
type User = {
  id: number;
  address?: {
    city?: string;
    state?: string; 
  } | null | undefined
}

// Prefer. Simpler. Clearer. Safer. 
type User = {
  id: number;
  address: {
    city: string;
    state: string; 
  } | null
}
150
Cory House @housecor.com · 04/11/2024
All these years I've been using "new Error" for nothing!? Just learned that these are equivalent in JS: throw Error('oops') and throw new Error('oops') Error() can be called with or without new. Both create a new Error instance.
1102
Cory House @housecor.com · 02/11/2024
I've spent the last few weeks trying all sorts of React 19 edge cases. (publishing vids on this soon) Realization: I rarely need useState anymore. React 19 offers focused alternatives. RSC, useActionState, useFormStatus, and useOptimistic replaced nearly all my useState calls.
030
Cory House @housecor.com · 31/10/2024
TypeScript has a structural type system, not a nominal type system. What's that mean? When determining if a type "fits", the type's *structure* matters. The type's name doesn't.
340