TypeScript extends JavaScript by adding a powerful static type system that helps catch errors at compile time rather than runtime. This post covers TypeScript fundamentals including built-in types, type annotations, arrays, tuples, and enums — everything you need to start writing type-safe code.
Built-in Types
Javascript has built-in types like :
- number
- string
- boolean
- null
- undefined
- object
For TypeScript built-in is like:
- any
- unknow
- never
- enum
- tuple
let sales: number = 123_456_789;let course: string = 'TypeScript';let is_published: boolean = true;
In TypeScript, we don't have to always have to annotate our variables, because the TypeScript compiler can infer or detect the type of our variables based on a value.
For example, if you remove annotation for sales then TypeScript automatically knows this sales variable is a number.
let sales = 123_456_789;let course = 'TypeScript';let is_published = true;
If you don't assign any values to a variable, TypeScript will know a variable is any type.
let level;
Any Type
In TypeScript, we have a new type called any, which can represent any kind of value. So if we declare a variable and don't initialize it, the TypeScript compiler assumes this variable is of type any. So we can set it to a number. And then later on, we can set it to a string. But this is against the whole idea of using TypeScript. Because we use TypeScript for as type safety. So we get type checking. So if we use the any type, we essentially lose that feature and the major benefit of using TypeScript. Best practice, we should avoid using any type as much as possible.
Arrays
In javascript, we can create an array like below:
let numbers = [1,2,'3'];
javascript arrays is that each element can be of different types. So here, we can have two numbers followed by a string. This is totally valid javascript code, because javascript arrays are dynamic.
In typescript, we can apply a type annotation for an array like below:
let numbers: number[] = [1,2,'3'];
We can see error immediately '3' is a string.
Tuples
TypeScript has a new type called tuple, which is a fixed-length array where each element has a particular type. We often use them when working with a pair of values.
let user: [number, string] = [1, 'Mosh'];
Enums
TypeScript has another built in type called enum, which represents a list of related constants. Let's say we have there const values like:
const small = 1;
const medium = 2;
const large = 3;
If we want to group these constants inside an enum, we can do like below
enum Size { Small =1, Medium = 2, Large = 3 }
use enum keyboard, then give our enum a name. We use Pascal naming convention.
If we want to get medium size from enum Size, we can do like below:
let mySize: Size = Size.Medium;
console.log(mySize);
Functions
Let's see how TypeScript helps us prevent common problems when working with functions. So, let's define a function call calculateTax, give it an income parameter of type number like below:
function calculateTax(income: number) {}
And then return a number value
function calculateTax(income: number) {return 0;}
Now, type of the return value is number. So the TypeScript compiler has inferred the type of the return value for us. That's great. But as a best practice, we should always properly annotate our functions. So all the parameters as well as the return type should be properly annotated. Especially when we are building APIs for other people to use. So in this case, to annotate the return type, we go after the list of parameters, add a colon and specify the return type, like number or void if we are not going to return a value. So let's add number like below:
function calculateTax(income: number):number {return 0;}
We add if condition inside function like below:
function calculateTax(income: number):number {if(income > 5000)return income * 1.2;}
Here TypeScript function will get compilation error because we never return value outside if condition. So we should return like below:
function calculateTax(income: number):number {if(income > 5000)return income * 1.2;return income * 1.5;}
In TypeScript very strict passing parameters into functions. For example, callback function have two parameters like below:
function calculateTax(income: number, taxYear: number):number {if(taxYear < 2020)return income * 1.2;return income * 1.5;}
we can't pass two more parameters for calculateTax function like below:
calculateTax(1000, 2020, 394);
When we working work with functions in TypeScript, we should uncomment some comments in tsconfig.json
"noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */"noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
Objects
Let's declare employee object
let employee = {id:1};
In Javascript objects are dynamic, so their shape can change throughout the lifetime or programs. So once we have an employee object, then later, we can give it a new property like name like below:
let employee = {id:1};employee.name = 'Linn';
This is totally valid in javascript. But this is not valid in TypeScript, the compiler will say property name does not exist on this type. So, we can do like below:
let employee : {id: number,name: string} = { id:1, name: "linn"};
If we want to readyonly some property, we can do like below:
let employee : {readonly id: number,name: string} = { id: 1, name: "linn"};
So, we can't reassign value for id.
Frequently Asked Questions
What are the built-in types in TypeScript?
TypeScript includes all JavaScript built-in types (number, string, boolean, null, undefined, object) plus additional types like any, unknown, never, enum, and tuple that enhance type safety.
What is the difference between any and unknown in TypeScript?
The any type disables type checking entirely, while unknown is a type-safe counterpart — you must perform type checks before performing operations on an unknown value.

