Ever spent hours debugging JavaScript only to find out a variable wasn't the type you thought? That's why TypeScript basic types exist. They aren't academic theory: they're the difference between code that breaks in production and code that holds up. We, at Meteora Web, use them daily in our Laravel, Vue, and custom WordPress projects. Our rule: a well-chosen type is a bug that never happens.
Why basic types matter
TypeScript adds a type system to JavaScript. Basic types are the building blocks: string, number, boolean, any, unknown, never, void. Using them wrong means writing TypeScript that's just JavaScript in disguise. Using them right means:
- Self-documenting code: readers instantly know what can be passed and returned.
- Fewer bugs: the compiler catches errors like adding strings to numbers.
- Safe refactoring: change a type and TypeScript shows every place to update.
Real example: when we optimized the ERP system for a clothing store, we migrated margin calculation logic from JavaScript to TypeScript. Result: zero type errors in season reports. Not theory.
Primitive types: string, number, boolean
These are the foundation. Always use them for simple values.
string
Represents a sequence of characters. In TypeScript you can declare a string in three ways:
let name: string = 'Meteora Web';
let description: string = `We are in Sciacca since 2017`; // template literal
let url: string = 'https://meteoraweb.com';
Common mistake: using String (the object) instead of string (the primitive). Don't: String is the wrapper object, rarely needed.
number
Covers integers, decimals, NaN, Infinity. No int/float distinction — everything is number.
let age: number = 35;
let price: number = 29.99;
let revenue: number = 1_000_000; // underscore as visual separator
Pro tip: for money, use number but watch rounding. For transactions, consider libraries like decimal.js.
boolean
True or false. Simple, but often misused:
let isActive: boolean = true;
let hasDiscount: boolean = false;
Common mistake: assigning 0 or '' to a boolean. TypeScript blocks it, but JavaScript doesn't. Be explicit.
any and unknown: the risk and the safety net
These two are often confused. We call them “the devil and the holy water”.
any: the type that disables checks
any tells TypeScript: “trust me, I know what I'm doing”. Consequently, no checks on called methods. It turns your TypeScript back into plain JavaScript.
let data: any = 'text';
data = 42; // ok
data.toUpperCase(); // runtime error because 42 has no toUpperCase
When to use: only during JS-to-TS migration, or for truly unpredictable data (e.g., response from a non-typed external API). But as soon as possible, replace it with a specific type or unknown.
unknown: the safe type
unknown is like any but forces you to check the type before using the value. It's the best choice for data whose shape you don't know.
let value: unknown = 'hello';
// value.toUpperCase(); // Error! Object is of type 'unknown'
if (typeof value === 'string') {
console.log(value.toUpperCase()); // OK, type narrowing
}
We use it often in API calls: before processing the response, we check the type with typeof or a schema (e.g., Zod). It reduces runtime crashes by 90%.
never and void: end of flow and absence of return
These types indicate what doesn't happen.
void: no value returned
Typical for functions that perform actions without returning anything (e.g., logging, saving to DB).
function logMessage(msg: string): void {
console.log(msg);
// no return
}
Note: void does not mean “undefined”. A void function can return undefined, but no other values. If you try return 42; TypeScript errors.
never: something that never occurs
never represents a value that can never happen. You'll see it in:
- Functions that always throw an exception.
- Infinite loops.
- Exhaustive switch checks.
function throwError(msg: string): never {
throw new Error(msg);
}
function infiniteLoop(): never {
while (true) {}
}
Practical use: when you switch on an enum, TypeScript can check all cases are covered. Add a default with never:
type OrderStatus = 'pending' | 'shipped' | 'delivered';
function handleStatus(s: OrderStatus) {
switch (s) {
case 'pending': break;
case 'shipped': break;
case 'delivered': break;
default:
const _exhaustive: never = s; // if you add a new status, error here
}
}
This pattern has saved us multiple times when we expanded state flows in our ERP.
Inline type annotations vs type inference
You don't always have to write the type. TypeScript infers well:
let name = 'Meteora'; // TypeScript infers: string
let count = 100; // infers: number
We prefer to explicitly annotate function parameters and return types (makes the contract clear), but let inference handle simple local variables. Balance.
Quick reference table — when to use what
| Type | When to use | When NOT to use |
|---|---|---|
| string | Text, URLs, emails, names | Numbers or booleans |
| number | Counts, prices, ages | Digits you don't compute (e.g., ZIP codes) |
| boolean | Flags, toggles, conditions | Instead of enumerated values |
| any | JS->TS migration, quick prototypes | Production code (replace ASAP) |
| unknown | External APIs, user input, unvalidated JSON | When you already know the type |
| never | Functions that throw errors, exhaustive switches | Values that can actually happen |
| void | Functions without meaningful return | Functions that return a value |
In summary — what to do now
- Review the types in your .ts files. Open any component. Check where you used
anyand replace withunknownor a union type. - Add explicit type annotations for parameters and returns of public functions.
- Implement an exhaustive check with
neverin every switch on enums or unions. - Use
unknownfor every API response not yet validated. Then narrow withtypeofor a library like Zod. - If you work in a team, agree on a policy: no
anyin merges to main. Use tools like ESLint with rule@typescript-eslint/no-explicit-any.
TypeScript's basic types are not bureaucracy: they're the net that stops your code from falling into the void. We, at Meteora Web, see it every day in projects we follow from idea to revenue. Want to dig deeper? Check our guide on ES2024 and ES2025 or the one on OOP in Python — concepts that intertwine with typing.
Sponsored Protocol