10 JavaScript/TypeScript features I avoid:


10 JavaScript/TypeScript features I avoid:

?.
?:
as
var
let
any
else
class
enum
switch

They’re not always a problem. But, they’re overused, and can often be replaced by better alternatives.

Here's why I avoid each, and what I do instead... 👇
?.

This is called optional chaining.

Example: user?.id

Why avoid it? Because it says "I'm not sure if this property exists."

Solution: Make sure it exists. Validate data (perhaps via Zod), and use a dedicated types for different permutations of data.
?:

This declares an optional field in TypeScript.

Example: user?: string

Why avoid it? Because it doesn't specify when the field should or shouldn't exist. It reduces type safety.

Solution: Declare separate, well-named types for when the field should and shouldn't exist.
as

The as keyword is a type assertion.

Why avoid it? Because it says "Trust me TypeScript, it's actually this type, so don't bother checking."

Solution: Use type narrowing.
var and let

These are inferior approaches to declaring a variable.

Why avoid them? Because they provide less information to the reader, and encourage writing mutative code.

Solution: Use const. It tells the reader "This variable's value may change, but it won't be reassigned"
any

Any disables TypeScript's type checking

Why avoid it? Because it makes TypeScript useless.

Solution: Declare a type.
else

The else keyword is combined with an if statement.

Why avoid it? Because it's a sign of mutative code. Prefer immutable patterns.

Solution: Make the assignment via a single expression, perhaps via a ternary.
class

The class keyword declares a JS class.

Why avoid it? Because functions are generally preferable, less confusing, and less error prone.

Solution: Write mostly pure functions. They're more composable and easier to test.
enum

This declares a TypeScript enum.

Why avoid it? Because there are generally superior alternatives.

Solution: Use a plain object, or a string union derived from an array marked as a const. https://stackoverflow.com/a/59420158/26180
switch

This creates conditional logic.

Why avoid it? Because it's often unnecessary, and reduces type safety if not exhaustive.

Solution: Combine a TypeScript Record with a union to enforce exhaustive checks. Or eliminate the switch altogether if possible by inverting control.
Many people replied with examples where these features are useful or even required.

I agree. 👍

That's why I said "I avoid them". There are good reasons these features exist.

My point is merely that they are overused, and often unnecessary, so I avoid them when I can.

View original on X