cd /news/developer-tools/typescript-types-demystified-simple-… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-33497] src=dev.to β†— pub= topic=developer-tools verified=true sentiment=Β· neutral

TypeScript Types Demystified: Simple Types, Special Types, and Type Inference

A developer explains TypeScript's type system, covering basic types, type inference, arrays, tuples, union types, and special types like any, unknown, never, and void. The post emphasizes letting TypeScript infer types for local variables while being explicit for function parameters and return types.

read6 min views1 publishedJun 19, 2026

In the first post, we covered why TypeScript exists and how to write your first program. Now it's time to get comfortable with the type system itself β€” the foundation everything else is built on.

By the end of this post, you'll know how to type variables, arrays, and function parameters correctly. You'll also understand the "special" types that trip up most beginners: any

, unknown

, never

, and void

.

TypeScript's basic types map directly to JavaScript's primitives:

// string
let firstName: string = "Ramesh";
let greeting: string = `Hello, ${firstName}`;

// number (no separate int/float β€” it's all number)
let age: number = 31;
let price: number = 9.99;
let hex: number = 0xFF;

// boolean
let isLoggedIn: boolean = true;
let hasAccess: boolean = false;

These are the types you'll use most often. Simple, predictable, and exactly what you'd expect.

You don't always have to write the type. TypeScript infers it from the value you assign:

let city = "Chennai";    // TypeScript infers: string
let year = 2026;         // TypeScript infers: number
let isActive = true;     // TypeScript infers: boolean

Once inferred, that type is locked in:

let city = "Chennai";
city = 42; // ❌ Error: Type 'number' is not assignable to type 'string'

Rule of thumb: Let TypeScript infer types for local variables. Write explicit annotations for function parameters and return types.

// Let inference work for variables
const scores = [95, 87, 72]; // inferred as number[]

// Be explicit for function signatures
function calculateAverage(scores: number[]): number {
  return scores.reduce((a, b) => a + b, 0) / scores.length;
}
// βœ… Explicit annotation β€” good for function params & return types
function formatName(first: string, last: string): string {
  return `${first} ${last}`;
}

// βœ… Inferred β€” good for simple variable assignments
const result = formatName("Ramesh", "Kumar"); // inferred as string

// ❌ Over-annotating β€” redundant when value makes it obvious
const count: number = 5; // The `= 5` already tells TypeScript it's a number

Arrays hold multiple values of the same type:

// Two equivalent syntaxes
let tags: string[] = ["typescript", "javascript", "react"];
let scores: Array<number> = [95, 87, 72];

// TypeScript will catch wrong types in arrays
tags.push(42); // ❌ Error: Argument of type 'number' is not assignable to type 'string'

Tuples are fixed-length arrays where each position has a specific type:

// A tuple: exactly [string, number]
let user: [string, number] = ["Ramesh", 31];

// Order and types are both enforced
let wrongOrder: [string, number] = [31, "Ramesh"]; // ❌ Error

// Accessing tuple elements
console.log(user[0]); // "Ramesh" β€” TypeScript knows this is string
console.log(user[1]); // 31 β€” TypeScript knows this is number

Tuples are great for things like coordinate pairs, key-value pairs, or when returning multiple values from a function:

function getMinMax(numbers: number[]): [number, number] {
  return [Math.min(...numbers), Math.max(...numbers)];
}

const [min, max] = getMinMax([3, 1, 7, 2, 9]);
// min: number, max: number β€” fully typed!

Sometimes a value can legitimately be more than one type. That's what union types handle:

// This function accepts string OR number
function formatId(id: string | number): string {
  return `ID-${id}`;
}

formatId("abc123"); // βœ…
formatId(42);       // βœ…
formatId(true);     // ❌ Error: boolean not in the union

Union types are especially useful for API responses, form inputs, and optional values:

// A status that can only be one of these three strings
let orderStatus: "pending" | "shipped" | "delivered";

orderStatus = "shipped";   // βœ…
orderStatus = "cancelled"; // ❌ Error: not in the union

// A value that might not exist yet
let userId: number | null = null;
userId = 101; // Fine, it's assigned now

any

, unknown

, never

, void

These four confuse most beginners. Here's each one explained clearly.

any

β€” The Escape Hatch (Use Sparingly) any

turns off TypeScript's type checking for that value:

let data: any = "hello";
data = 42;        // Fine
data = true;      // Fine
data.foo.bar();   // Fine β€” no error, even if this blows up at runtime!

When to use it: Almost never. any

defeats the purpose of TypeScript. It's there as a last resort when migrating old JavaScript code.

// ❌ Overusing any β€” you've lost all type safety
function processData(input: any): any { ... }

// βœ… Be specific whenever possible
function processData(input: string[]): number { ... }

unknown

β€” The Safe Version of any

unknown

says "this could be anything, but I need to check before I use it":

let userInput: unknown = getUserInput();

// ❌ Can't use unknown directly
console.log(userInput.toUpperCase()); // Error!

// βœ… Must narrow the type first
if (typeof userInput === "string") {
  console.log(userInput.toUpperCase()); // Now it's safe
}

Prefer unknown over any when you genuinely don't know the type. It forces you to handle the uncertainty explicitly.

void

β€” Functions That Return Nothing Use void

when a function doesn't return a value:

function logMessage(message: string): void {
  console.log(message);
  // No return statement needed
}

// Trying to use the return value of a void function makes no sense
const result = logMessage("hello"); // result is void β€” useless

never

β€” Code That Never Completes never

represents values that never occur. It's used for:

// Always throws β€” never returns
function throwError(message: string): never {
  throw new Error(message);
}

// Exhaustive check β€” if you add a new status and forget to handle it,
// TypeScript will error here
function handleStatus(status: "active" | "inactive"): string {
  if (status === "active") return "User is active";
  if (status === "inactive") return "User is inactive";

  // This line should be unreachable
  const _exhaustive: never = status; // ❌ Error if you missed a case
  return _exhaustive;
}

never

is an advanced concept β€” don't worry if it doesn't fully click yet. You'll encounter it naturally as you write more TypeScript.

// Primitives
let name: string = "Ramesh";
let age: number = 31;
let active: boolean = true;

// Arrays
let tags: string[] = ["ts", "js"];
let ids: number[] = [1, 2, 3];

// Tuples
let point: [number, number] = [10, 20];

// Union
let id: string | number = "abc";
let status: "on" | "off" = "on";

// Special types
let anything: any = "...";     // Avoid when possible
let safeAny: unknown = "...";  // Safer β€” must narrow before use
function log(): void { ... }   // No return value
function fail(): never { throw new Error(); } // Never returns

The TypeScript type system is deep, but the everyday usage is straightforward. Here's what to take away:

string

, number

, boolean

cover most casesstring[]

or Array<string>

, your choiceany

unknown

void

never

Found this helpful? Follow for the rest of the series. Questions or corrections? Drop them in the comments.

── more in #developer-tools 4 stories Β· sorted by recency
── more on @typescript 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/typescript-types-dem…] indexed:0 read:6min 2026-06-19 Β· β€”