myHotTake

Tag: TypeScript coding

  • How Can I Avoid Overusing any in TypeScript?

    If you find this story helpful, feel free to like or share it with others who might be interested!


    I’m running a pet hotel. It’s a place where dogs, cats, birds, and even the occasional iguana come to stay while their owners are away. Now, in this pet hotel, there’s a room called “The Any Room.” It’s a place where any animal can go, no questions asked. Sounds convenient, right? But here’s the catch: because it’s open to all, I never really know what kind of animal might show up there, and it makes it incredibly hard to cater to their specific needs.

    One day, a dog, a cat, and an iguana all check into The Any Room. The dog needs a walk, the cat needs a quiet corner, and the iguana requires a heat lamp. But because they’re all mixed up in The Any Room, I can’t easily provide what each one needs without some confusion. I find myself constantly running back and forth, trying to figure out what belongs to whom. It’s chaos!

    So, I decide to make a change. I start creating specific rooms for each type of animal. Now, there’s a “Dog Room” with plenty of toys and space to run, a “Cat Room” with cozy nooks and scratching posts, and an “Iguana Room” complete with the perfect heat lamp. By organizing my pet hotel this way, I can cater to each animal’s unique needs without the headache.

    In the world of TypeScript, overusing the any type is like relying too much on The Any Room. It might seem convenient at first, but it leads to confusion and errors because I can’t anticipate the specific needs or behaviors of the data. By using more specific types, much like my organized pet rooms, I ensure that my code is clear, predictable, and maintainable. This way, each piece of data gets exactly what it needs, just like the happy animals in my newly organized pet hotel.


    Continuing with my pet hotel, imagine I’ve decided to track the animals in a computer system. Initially, I might be tempted to use the any type for each animal, just like The Any Room, to keep things simple:

    let animal: any;
    
    animal = { type: 'dog', name: 'Buddy', needsWalk: true };
    animal = { type: 'cat', name: 'Whiskers', likesToClimb: true };
    animal = { type: 'iguana', name: 'Iggy', requiresHeatLamp: true };

    This allows me to store any animal, but it doesn’t provide me with information or safety about what properties each animal should have. When I try to access a property like needsWalk, I have no guarantee it exists on the current animal:

    if (animal.needsWalk) {
      console.log(`${animal.name} needs a walk.`);
    }

    This could lead to runtime errors if animal is, say, a cat or an iguana.

    To address this, I start to define more specific types, much like creating separate rooms in the hotel:

    type Dog = {
      type: 'dog';
      name: string;
      needsWalk: boolean;
    };
    
    type Cat = {
      type: 'cat';
      name: string;
      likesToClimb: boolean;
    };
    
    type Iguana = {
      type: 'iguana';
      name: string;
      requiresHeatLamp: boolean;
    };
    
    let specificAnimal: Dog | Cat | Iguana;
    
    specificAnimal = { type: 'dog', name: 'Buddy', needsWalk: true };
    // Now TypeScript knows exactly what properties are available
    
    if (specificAnimal.type === 'dog' && specificAnimal.needsWalk) {
      console.log(`${specificAnimal.name} needs a walk.`);
    }

    By using these specific types, I make sure that I only access properties that are relevant to the type of animal I’m dealing with. This prevents errors and makes my code more predictable and easier to maintain.


    Key Takeaways:

    • Avoid Overuse of any: Just like the confusing Any Room in my pet hotel, using any can lead to unexpected errors and complications in your code. It sacrifices type safety and predictability.
    • Use Specific Types: Define specific types for different data entities in your application. This helps ensure type safety and makes your code more maintainable and understandable.
    • Type Safety: Leveraging TypeScript’s static type checking prevents many common runtime errors and improves the reliability of your code.