How to fix Cannot use 'X' as a value in TypeScript

TypeScriptINTERMEDIATEHIGHUpdated Dec 8, 2025· 132 views

This error occurs when you try to use a type, interface, or type alias at runtime where a value is expected. In TypeScript, types only exist during compilation and are erased at runtime, so they cannot be used as JavaScript values.

Quick fix

Fixes TS2693

interface User {
  id: number;
  name: string;
}

// ❌ Error: Cannot use 'User' as a value
if (obj instanceof User) {
  console.log("It's a User");
}
  1. Identify the problematic type usage
  2. Convert the interface to a class (if possible)
  3. Create a user-defined type guard function
  4. Use type-only imports if applicable
typescript — error
interface User {
id: number;
name: string;
}
// ❌ Error: Cannot use 'User' as a value
if (obj instanceof User) {
console.log("It's a User");
}
Cannot use 'X' as a value

What this error means

TypeScript has two separate namespaces: types and values. Type definitions (interfaces, type aliases, abstract classes) exist only during compilation and are completely removed when your TypeScript code is transpiled to JavaScript. When you try to use a type name in a context that requires a runtime value—such as with the `instanceof` operator, function calls, or object properties—TypeScript throws this error because that type name doesn't exist as a value at runtime. For example, you can use `Employee` as a type annotation in `let emp: Employee`, but you cannot use it as a value in `instanceof Employee` because there's no actual JavaScript value to check against.

Typical symptoms

  • Error message: 'X' only refers to a type, but is being used as a value here
  • Attempting to use instanceof with an interface or type alias
  • Trying to pass a type as an argument to a function
  • Attempting to use a type name in conditionals or expressions
  • Trying to return a type or assign it to a variable
  • Using a type with operators like typeof or instanceof

Common causes

  1. Using instanceof with an interface or type alias instead of a class (most common)
  2. Trying to use a type name as a function argument or return value
  3. Confusing type-only imports with regular imports
  4. Using a namespace or type alias where a value is required
  5. Attempting to spread or destructure a type
  6. Using a generic type at runtime without a value wrapper

How to fix "Cannot use 'X' as a value"

1Identify the problematic type usage

First, locate the line causing the error. You'll see something like:

typescript
interface User {
  id: number;
  name: string;
}

// ❌ Error: Cannot use 'User' as a value
if (obj instanceof User) {
  console.log("It's a User");
}

The error occurs because User is an interface (compile-time only), not a runtime value.

2Convert the interface to a class (if possible)

The simplest fix is to change the interface to a class. Classes exist at runtime and can be used with instanceof:

typescript
// ✅ Instead of interface, use class
class User {
  constructor(
    readonly id: number,
    readonly name: string
  ) {}
}

if (obj instanceof User) {
  console.log("It's a User");
}

Classes provide both type-checking (like interfaces) and runtime values.

3Create a user-defined type guard function

If you need to keep the interface, create a runtime function to check the properties:

typescript
interface User {
  id: number;
  name: string;
}

// Define a type guard function
function isUser(obj: unknown): obj is User {
  return (
    typeof obj === "object" &&
    obj !== null &&
    "id" in obj &&
    "name" in obj &&
    typeof (obj as any).id === "number" &&
    typeof (obj as any).name === "string"
  );
}

// ✅ Use the type guard instead of instanceof
if (isUser(obj)) {
  console.log("It's a User");
}
4Use type-only imports if applicable

If you're importing a type that doesn't exist as a value, ensure you're using import type:

typescript
// ✅ Correct - type-only import
import type { User } from "./types";

// Use User only in type annotations, never as a value
let user: User;

// ❌ This would still error
// const UserClass = User; // Can't use User as a value

Type-only imports explicitly tell TypeScript to erase the import, preventing accidental runtime usage.

5Verify your fix

Compile your TypeScript to ensure the error is gone:

bash
npx tsc --noEmit

Or run your dev server:

bash
npm run dev

The error should now be resolved, and your code will compile successfully.

Advanced notes

### Type Assertion Workaround (Not Recommended)

In some cases, you might see a workaround using type assertions with typeof:

typescript
type UserType = typeof SomeClass;

This only works when there's an underlying value (like a class). For pure interfaces, this approach fails.

### Discriminated Unions as a Type-Safe Alternative

Instead of relying on instanceof, use discriminated unions for better type safety:

typescript
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function getArea(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.side ** 2;
  }
}

This pattern is more idiomatic in TypeScript and avoids runtime type checking entirely.

### Zod and Runtime Validation Libraries

For complex data validation, consider libraries like Zod, io-ts, or Yup:

typescript
import { z } from "zod";

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
});

type User = z.infer<typeof UserSchema>;

// ✅ Safe runtime validation
const user = UserSchema.parse(unknownData);

These libraries provide both type safety and runtime validation.

### Enum as a Type-Safe Alternative

For a fixed set of values, use enums instead of type unions:

typescript
enum UserRole {
  Admin = "admin",
  User = "user",
  Guest = "guest",
}

// Enums exist at runtime, so this works
function checkRole(role: unknown): role is UserRole {
  return Object.values(UserRole).includes(role);
}

Frequently asked questions

What does "TS2693" mean?
TypeScript has two separate namespaces: types and values. Type definitions (interfaces, type aliases, abstract classes) exist only during compilation and are completely removed when your TypeScript code is transpiled to JavaScript. When you try to use a type name in a context that requires a runtime value—such as with the instanceof operator, function calls, or object properties—TypeScript throws this error because that type name doesn't exist as a value at runtime.
How do I fix "TS2693"?
This error occurs when you try to use a type, interface, or type alias at runtime where a value is expected. In TypeScript, types only exist during compilation and are erased at runtime, so they cannot be used as JavaScript values.
What causes "TS2693"?
Using instanceof with an interface or type alias instead of a class (most common) Trying to use a type name as a function argument or return value Confusing type-only imports with regular imports
Is the "TS2693" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading