Ad Space — Top Banner

TS2693

TypeScript Programming Language

Severity: Moderate

What Does This Error Mean?

TypeScript error TS2693 means you are using a TypeScript type, interface, or type alias as if it were a runtime value. Types in TypeScript exist only at compile time — they are erased and do not exist in the JavaScript output. You cannot use a type in an expression position (like calling it as a function or using it in an if statement). Common causes are trying to use typeof on a TypeScript interface or using a type in a switch/case.

Affected Models

  • TypeScript 4.x
  • TypeScript 5.x
  • VS Code
  • WebStorm
  • Any TypeScript project

Common Causes

  • Using an interface or type alias as a constructor or function call (e.g., new MyInterface())
  • Checking a value against a type using === instead of a type guard function
  • Using a type in a JavaScript expression position such as console.log(MyType)
  • Confusing a TypeScript enum (which is a value) with a plain type alias or interface
  • Trying to pass a type as a generic argument incorrectly in a runtime context

How to Fix It

  1. Understand the distinction: TypeScript types (interface, type, generics) exist only during compilation. JavaScript values (classes, objects, functions, enums) exist at runtime. You cannot mix them.

    A useful mental model: if you can console.log() it, it is a value. If TypeScript only knows about it at compile time, it is a type and cannot be used in expressions.

  2. If you need runtime type checking, use a class instead of an interface. Classes generate both a TypeScript type AND a JavaScript constructor that can be used with instanceof at runtime.

    Example: class User { ... } allows both: const u: User = new User() (type usage) and if (x instanceof User) (runtime check).

  3. If you need to check a type at runtime, write a type guard function. A type guard is a function that returns a boolean and uses the 'is' keyword: function isUser(x: unknown): x is User { return typeof x === 'object' && x !== null && 'id' in x; }

    Type guards let TypeScript narrow types based on runtime checks without needing the type to exist as a JavaScript value.

  4. If you intended to use an enum, make sure you defined it as a TypeScript enum (enum Status { Active, Inactive }) not as a type alias. Enums generate real JavaScript objects that can be used as values.

    Note: const enum is erased at compile time and cannot be used as a runtime value in some module systems. Use a regular enum if you need runtime access.

  5. If you see this error when using generics, check that you are not trying to use a generic type parameter T as a value. Generic type parameters are erased at runtime and cannot be instantiated or compared directly.

    Example: function create<T>() { return new T(); } causes TS2693 — T is a type parameter and cannot be constructed. Pass the constructor itself as an argument instead.

When to Call a Professional

TS2693 is a fundamental TypeScript concept error — types are compile-time only. No external service is needed. Understanding the difference between TypeScript types and JavaScript values resolves this error.

Frequently Asked Questions

Why does TypeScript erase types at compile time?

TypeScript's type system is designed to add zero runtime overhead to JavaScript. Types are only needed by the TypeScript compiler to check correctness — the generated JavaScript output has no type annotations. This means TypeScript-only constructs (interface, type, generics) do not exist in the JavaScript your browser or Node.js runs. JavaScript's built-in instanceof and typeof operators are the runtime equivalents for type checking.

What is the difference between an interface and a class in TypeScript?

An interface is a compile-time-only contract — it describes the shape of an object but generates no JavaScript code. A class is both a type description AND a JavaScript constructor function that exists at runtime. Use an interface when you only need to describe a type for compile-time checking. Use a class when you need constructors, methods, inheritance, or instanceof checks at runtime.

Can I use a TypeScript type as a generic constraint?

Yes — using a type as a generic constraint is a compile-time operation and is perfectly valid. Example: function process<T extends MyInterface>(value: T) is fine — TypeScript uses the interface constraint at compile time only. The error TS2693 only occurs when you try to use a type in a position where JavaScript code runs at runtime, not in type annotations or generic constraints.