TypeScript Basic Types: Strings, Numbers, Booleans, Arrays, and More
TypeScript basic types are the building blocks you use to describe what values your variables, function parameters, and return values can hold. Learning them helps you catch mistakes early, write clearer code, and make your intent obvious to other developers.
Quick answer: TypeScript basic types let you label values such as string, number, boolean, arrays, tuples, and a few special types like any and unknown. These labels help the compiler check your code before it runs.
Difficulty: Beginner
You'll understand this better if you know: basic JavaScript variables, functions, and how values like text and numbers work in code.
1. What Is TypeScript Basic Types?
TypeScript basic types are the simplest type annotations you can add to JavaScript code. They describe the shape of data so TypeScript can warn you when you try to use the wrong kind of value.
- string is for text.
- number is for numeric values, including decimals.
- boolean is for true/false values.
- array types describe lists of values.
- tuple types describe fixed-length lists with known positions.
- any, unknown, void, null, and undefined cover special cases.
These types are the starting point for almost every TypeScript file. Even when you later use interfaces, generics, or utility types, you still rely on these basic building blocks.
2. Why TypeScript Basic Types Matters
Basic types matter because they help you find bugs before runtime. Without types, a function might accidentally receive a number where it expects text, or return a value in the wrong format.
TypeScript uses basic types to improve autocomplete, documentation, and refactoring safety. When your values are typed well, editors can show better suggestions and catch mistakes as you type.
They also make code easier to read. A variable named age is clearer when it is explicitly typed as number, and a function that returns boolean clearly signals a yes-or-no result.
3. Basic Syntax or Core Idea
TypeScript types are usually written with a colon after a variable, parameter, or return value. The type comes after the colon and before any assignment value when applicable.
Type annotation examples
let username: string = "Amina";
let age: number = 28;
let isActive: boolean = true;This tells TypeScript that username must always hold text, age must always hold a numeric value, and isActive must always be either true or false.
Function parameter and return types
function formatUser(name: string, points: number): string {
return `${name} has ${points} points`;
}The parameters are typed individually, and the return type comes after the closing parenthesis. This makes the function contract explicit.
Array syntax
let tags: string[] = ["typescript", "types", "javascript"];The string[] form means “an array of strings.”
4. Step-by-Step Examples
Example 1: Text, numbers, and booleans together
This example shows the most common primitive types in a small profile object.
let firstName: string = "Maya";
let loginCount: number = 12;
let subscribed: boolean = false;
console.log(firstName, loginCount, subscribed);TypeScript checks each assignment. If you later try to put a string into loginCount, the compiler will stop you.
Example 2: Arrays of one value type
Arrays are useful when all items should be the same type.
let scores: number[] = [10, 20, 30];
let labels: Array<string> = ["low", "medium", "high"];Both forms mean the same thing for simple arrays. Use whichever style your team prefers, but stay consistent in one codebase.
Example 3: Tuples for fixed positions
Tuples are helpful when each index means something different.
let userRecord: [string, number] = ["Nora", 34];
let nameFromTuple = userRecord[0];
let ageFromTuple = userRecord[1];Here, position matters. Index 0 is always a string and index 1 is always a number.
Example 4: Special types in function behavior
Special types often appear in functions that do not return a useful value, or in variables that may start empty.
function logMessage(message: string): void {
console.log(message);
}
let rawValue: unknown = "42";void means the function does not return a meaningful value. unknown means you have a value, but you must check it before using it safely.
5. Practical Use Cases
- Typing form values, API results, and component-free utility code in a small app.
- Describing data you pass between functions, such as string IDs, numeric counters, or boolean flags.
- Modeling fixed record pairs with tuples, such as [latitude, longitude] or [label, value].
- Protecting code that parses JSON by using unknown before validation.
- Documenting function behavior with void return types when a function only performs an action.
These types are especially useful in application code where many bugs come from incorrect assumptions about values coming from users, files, or network responses.
6. Common Mistakes
Mistake 1: Using the wrong primitive type
It is common to confuse values that look similar, especially strings and numbers. TypeScript will reject the assignment if the annotation does not match the actual value.
Problem: This code says the value is a number, but the assigned value is text, so the type check fails.
let port: number = "3000";Fix: Store numbers as numbers, or convert the value before assigning it.
let port: number = 3000;
let portFromInput: string = "3000";
let numericPort = Number(portFromInput);The corrected version works because each variable stores a value that matches its type or converts it first.
Mistake 2: Treating arrays as if they can hold any mix of values
When you type an array as string[], every item must be a string. Mixing in another type causes a compiler error.
Problem: This array mixes strings and numbers, which does not satisfy the declared element type.
let items: string[] = ["apple", 2, "pear"];Fix: Use a single element type, or describe a union if mixed values are truly expected.
let items: string[] = ["apple", "2", "pear"];
let mixedItems: (string | number)[] = ["apple", 2, "pear"];The corrected version works because the array type now matches the actual data you want to store.
Mistake 3: Using any when unknown is safer
any disables type checking, which can hide bugs until runtime. unknown forces you to validate before using the value.
Problem: This code assumes a value is a string, but any prevents TypeScript from warning you if it is not.
let payload: any = JSON.parse('{"name":"Priya"}');
let upper = payload.toUpperCase();Fix: Use unknown and narrow the type before calling string methods.
let payload: unknown = JSON.parse('{"name":"Priya"}');
if (typeof payload === "string") {
let upper = payload.toUpperCase();
}The corrected version works because TypeScript can verify the type before you use the value.
7. Best Practices
Practice 1: Prefer explicit types for public function boundaries
Annotating function parameters and return values makes your code easier to reuse and safer to refactor.
function buildLabel(name: string, count: number): string {
return `${name}: ${count}`;
}Callers can immediately see what the function expects, and TypeScript can catch mismatches near the call site.
Practice 2: Use unknown for untrusted data
When data comes from outside your program, treat it as unknown until you verify it.
function printValue(value: unknown) {
if (typeof value === "string") {
console.log(value.toUpperCase());
}
}This pattern prevents unsafe property access and keeps validation visible in the code.
Practice 3: Use tuples only when position is meaningful
If the meaning of each slot is fixed, tuples can be clearer than a loosely typed array.
let coordinates: [number, number] = [51.5074, 0.1278];This works well for compact, positional data, but not for collections whose length can change freely.
8. Limitations and Edge Cases
- number covers both integers and decimals in TypeScript, because JavaScript has a single numeric type.
- array types can be written in two common forms: T[] and Array<T>.
- tuple types are fixed in order and often in length, but they can still be expanded with optional elements or rest elements in more advanced cases.
- any turns off useful checking, so it can hide bugs that only appear at runtime.
- null and undefined are distinct values, and their behavior depends on your compiler settings, especially strictNullChecks.
- Literal values such as "admin" or 42 can be preserved more narrowly than their broader primitive types, which is useful but easy to confuse with the basics.
- TypeScript types are erased when code runs, so they protect you during development but do not create runtime validation by themselves.
One common surprise is that a value may type-check but still fail at runtime if you trusted input that was not actually validated. TypeScript helps a lot, but it does not replace careful data checking.
9. Practical Mini Project
Let’s build a tiny profile summary function that uses several basic types together. This shows how they fit into a realistic helper that could be used in an app.
type Profile = {
name: string;
age: number;
isAdmin: boolean;
tags: string[];
};
function makeSummary(profile: Profile): string {
let role = profile.isAdmin ? "admin" : "member";
let tagList = profile.tags.join(", ");
return `${profile.name} is ${profile.age} years old, ${role}, and tagged with ${tagList}`;
}
let output = makeSummary({
name: "Ivy",
age: 31,
isAdmin: false,
tags: ["frontend", "typescript"]
});
console.log(output);This small project uses a text field, a numeric field, a boolean flag, and an array of strings. It also shows how basic types become more useful when combined into a typed object and a function contract.
10. Key Points
- string, number, and boolean are the most common TypeScript basic types.
- Use T[] or Array<T> for arrays of one type.
- Use tuples when each position has a fixed meaning.
- Use void for functions that do not return a useful value.
- Use unknown instead of any when data must be checked first.
- Type annotations help TypeScript catch mistakes before runtime.
- Types improve readability, autocompletion, and long-term maintenance.
11. Practice Exercise
Try writing a small typed helper that formats product information.
- Create variables for a product name (string), price (number), and inStock (boolean).
- Write a function that returns a string summary using those values.
- Add a string array of product tags and include them in the summary.
- Make sure the function has explicit parameter and return types.
Expected output: A single formatted string such as "Notebook costs 4.99 and is in stock".
Hint: Use a template string and remember that the tags array should be typed as string[].
Solution:
let productName: string = "Notebook";
let price: number = 4.99;
let inStock: boolean = true;
let tags: string[] = ["stationery", "office"];
function formatProduct(name: string, productPrice: number, stocked: boolean, productTags: string[]): string {
let availability = stocked ? "in stock" : "out of stock";
return `${name} costs ${productPrice} and is ${availability} (tags: ${productTags.join(", ")})`;
}
let summary = formatProduct(productName, price, inStock, tags);
console.log(summary);12. Final Summary
TypeScript basic types are the foundation of type-safe JavaScript. They let you describe everyday values like text, numbers, booleans, arrays, tuples, and special cases such as unknown and void. Once you understand these building blocks, it becomes much easier to type functions, objects, and real application data.
For beginners, the biggest win is learning to match the type annotation to the actual value you want to store. For intermediate developers, the real benefit is using those types to prevent bugs, improve refactoring, and make code contracts easy to understand.
Next, practice combining basic types in typed objects and function signatures. That is where TypeScript starts to feel less like extra syntax and more like a practical tool for writing safer JavaScript.