HomeBlogTypeScript
TypeScript

TypeScript vs JavaScript: Key Differences Tested in Every Interview

Interviewers expect you to know TypeScript beyond just 'it adds types'. Here are the features that trip up JS developers — with examples of how they're tested.

Examifyr·Aug 2026·7 min read

Most JavaScript developers pick up TypeScript quickly — the syntax is familiar, and the basics feel natural. But interviews dig deeper. They want to see whether you actually understand how the type system works, not just whether you can annotate a variable.

These are the differences that show up on TypeScript quizzes and interviews — and where JS muscle memory leads you wrong.

1. Structural typing: types match by shape, not name

TypeScript uses structural typing. A type is compatible if it has the right properties — the name doesn't matter. This surprises developers coming from languages like Java or C#.

interface Point {
  x: number;
  y: number;
}

interface Coordinate {
  x: number;
  y: number;
}

function plot(p: Point) { /* ... */ }

const c: Coordinate = { x: 1, y: 2 };
plot(c); // ✅ Works — same shape, TypeScript doesn't care about the name

Exam tip: When two object types have the same properties, TypeScript treats them as compatible — even if they're declared with different names. This is called "duck typing" at the type level.

2. type vs interface — more similar than you think

A common interview question is "what's the difference between type and interface?". The honest answer: mostly interchangeable for object shapes, with two key differences.

// interface: can be extended and merged (declaration merging)
interface User {
  id: number;
}
interface User {
  name: string; // ✅ Adds to the existing User — declaration merging
}

// type: cannot be re-opened; use intersection (&) to extend
type Admin = User & { role: string }; // ✅ Extends via intersection
// type User = { extra: string }; // ❌ Error: duplicate identifier

Use interface when defining object shapes that may be extended (especially in library code). Use type for unions, intersections, and aliases where merging would be confusing.

3. Union types and narrowing

Union types let a value be one of several types. The tricky part is narrowing — telling TypeScript which branch you're in.

function format(value: string | number): string {
  if (typeof value === 'string') {
    return value.toUpperCase(); // TypeScript knows it's a string here
  }
  return value.toFixed(2); // TypeScript knows it's a number here
}

// Discriminated unions — common in React state machines
type State =
  | { status: 'loading' }
  | { status: 'success'; data: string }
  | { status: 'error'; message: string };

function handle(state: State) {
  if (state.status === 'success') {
    console.log(state.data); // ✅ Narrowed — data is accessible
  }
}

Exam tip: TypeScript narrows unions using typeof, instanceof, in, and literal property checks (discriminated unions). Know all four.

4. Generics — not just for collections

Generics let you write type-safe functions without hardcoding a specific type. Interviewers test whether you can read and write simple generic functions, not just pass arrays to them.

// Generic identity function
function identity<T>(value: T): T {
  return value;
}

identity(42);       // T inferred as number
identity('hello'); // T inferred as string

// Generic with constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { id: 1, name: 'Alice' };
getProperty(user, 'name'); // ✅ returns string
// getProperty(user, 'age'); // ❌ 'age' is not a key of user

The extends keyof T pattern comes up constantly. It means "K must be a valid key of T" — TypeScript then knows the return type is T[K].

5. any vs unknown — never use any in an interview

Both any and unknown accept any value, but they behave oppositely when you try to use the value.

let a: any = "hello";
a.toUpperCase(); // ✅ No error — TypeScript turns off checks for 'any'
a.nonExistent(); // ✅ Also no error — this is the danger

let u: unknown = "hello";
// u.toUpperCase(); // ❌ Error: must narrow first

if (typeof u === 'string') {
  u.toUpperCase(); // ✅ Safe — narrowed to string
}

In interviews, saying "I use unknown when the type is genuinely not known, then narrow before use" signals you understand type safety. Reaching for any is a red flag.

6. readonly and const — different guarantees

const prevents reassignment at runtime. readonly prevents property mutation at the type level.

const arr = [1, 2, 3];
arr.push(4); // ✅ Runtime: const doesn't prevent mutation of the value

const readonlyArr: readonly number[] = [1, 2, 3];
// readonlyArr.push(4); // ❌ Type error: push doesn't exist on readonly

interface Config {
  readonly apiUrl: string;
}
const config: Config = { apiUrl: 'https://api.example.com' };
// config.apiUrl = 'other'; // ❌ Type error: cannot assign to readonly property

7. Type assertions vs type guards

A type assertion (as SomeType) tells TypeScript "trust me, I know better." A type guard proves the type through a check TypeScript can verify.

// Type assertion — bypasses checks, can be wrong
const input = document.getElementById('email') as HTMLInputElement;
input.value; // TypeScript trusts you — if it's not an input, this blows up at runtime

// Type guard — safe narrowing the compiler can verify
function isError(value: unknown): value is Error {
  return value instanceof Error;
}

try { /* ... */ } catch (e) {
  if (isError(e)) {
    console.log(e.message); // ✅ TypeScript knows it's an Error
  }
}

Prefer type guards over assertions whenever possible. Assertions are useful for DOM work and migration from JS, but they shift responsibility for correctness to you.

Quick reference: JavaScript vs TypeScript behaviour

JavaScript                          TypeScript
────────────────────────────────────────────────────────
let x = 5; x = "hi"      ✅       let x = 5; x = "hi"   ❌ Type error
typeof check at runtime only        Compile-time + narrowing
No interface/type keywords          interface / type define shapes
Errors at runtime                   Errors at compile time (+ editor)
any implicit everywhere             Explicit typing + strict mode

Practice this on Examifyr: The TypeScript quiz covers union types, generics, type vs interface, and narrowing — the exact areas tested in front-end interviews. Take it to find your gaps before your next interview.

🎯

Think you're ready? Prove it.

Take the free TypeScript readiness test. Get a score from 0–100, a topic breakdown, and your exact weak areas — in under 20 minutes.

Take the free TypeScript test →

Free · No sign-up · Instant results

More from Examifyr

← All articles