How to fix Type 'string' is not assignable to type 'number' in TypeScript

TypeScriptBEGINNERLOWUpdated Dec 11, 2025· 182 views

This TypeScript error occurs when attempting to assign a string value to a variable, property, or parameter that expects a number type. TypeScript's static type checking prevents this at compile time to avoid runtime type errors.

Quick fix

Fixes Type 'string' is not assignable to type 'number'

// Before: Type error
let age: number = "25"; // Error: Type 'string' is not assignable to type 'number'

// After: Correct conversion
let age: number = Number("25"); // age = 25

// Works with decimals
let price: number = Number("19.99"); // price = 19.99

// Returns NaN for invalid inputs
let invalid: number = Number("abc"); // invalid = NaN
  1. Use Number() constructor for explicit conversion
  2. Use parseInt() for integer conversion
  3. Use parseFloat() for decimal numbers
  4. Use the unary plus operator for quick conversion
typescript — error
// Before: Type error
let age: number = "25"; // Error: Type 'string' is not assignable to type 'number'
// After: Correct conversion
let age: number = Number("25"); // age = 25
// Works with decimals
let price: number = Number("19.99"); // price = 19.99
// Returns NaN for invalid inputs
let invalid: number = Number("abc"); // invalid = NaN
Type 'string' is not assignable to type 'number'

What this error means

This error is TypeScript's way of enforcing type safety during compile time. When you declare a variable, parameter, or property with a specific type (in this case, `number`), TypeScript ensures that only values of that type can be assigned to it. The error "Type 'string' is not assignable to type 'number'" indicates that you're trying to assign a string value where TypeScript expects a number. This commonly occurs when reading data from HTML inputs, API responses, URL parameters, or environment variables—sources that typically return string values even when they contain numeric characters. TypeScript prevents this assignment because strings and numbers are fundamentally different types with different operations and behaviors. For example, the string "5" + "3" equals "53" (concatenation), while the number 5 + 3 equals 8 (addition). By catching these mismatches at compile time, TypeScript helps prevent subtle runtime bugs that would be difficult to debug.

Typical symptoms

  • Compiler error appears when assigning values from input fields, API responses, or URL parameters to number-typed variables
  • TypeScript build fails with error code TS2322
  • Red squiggly lines appear in your IDE under the assignment statement
  • Error message shows the exact types that are incompatible in the assignment
  • Code works in plain JavaScript but fails when migrating to TypeScript

Common causes

  1. Attempting to assign a string value directly to a number-typed variable without conversion
  2. Reading values from HTML input elements, which always return strings via .value property
  3. Parsing data from URL query parameters or route parameters, which are strings by default
  4. Receiving data from API responses as strings instead of numbers (especially in JSON where numbers may be quoted)
  5. Reading environment variables or configuration values that are stored as strings
  6. Using incorrect type annotations that don't match the actual data source
  7. Forgetting to convert string data after validation or sanitization steps

How to fix "Type 'string' is not assignable to type 'number'"

1Use Number() constructor for explicit conversion

The Number() constructor is the most versatile method for converting strings to numbers. It handles both integers and floating-point numbers:

typescript
// Before: Type error
let age: number = "25"; // Error: Type 'string' is not assignable to type 'number'

// After: Correct conversion
let age: number = Number("25"); // age = 25

// Works with decimals
let price: number = Number("19.99"); // price = 19.99

// Returns NaN for invalid inputs
let invalid: number = Number("abc"); // invalid = NaN

Always check for NaN after conversion if the input might be invalid:

typescript
const input = "123";
const value = Number(input);

if (isNaN(value)) {
  console.error("Invalid number input");
} else {
  console.log("Valid number:", value);
}
2Use parseInt() for integer conversion

When you specifically need an integer (whole number), use parseInt(). This function parses a string and returns an integer, optionally specifying the radix (base):

typescript
// Parse decimal integers
let count: number = parseInt("42", 10); // count = 42

// Automatically removes decimal portion
let rounded: number = parseInt("42.7", 10); // rounded = 42

// Handles leading whitespace
let spaced: number = parseInt("  100", 10); // spaced = 100

// Can extract numbers from mixed strings
let mixed: number = parseInt("123abc", 10); // mixed = 123

Always specify the radix (second parameter) to avoid unexpected behavior:

typescript
// Good: explicit radix
parseInt("08", 10); // 8

// Bad: implicit radix (older JS versions might interpret as octal)
parseInt("08"); // Could be 0 in older environments
3Use parseFloat() for decimal numbers

For strings containing decimal numbers, use parseFloat() to preserve the fractional part:

typescript
// Parse floating-point numbers
let temperature: number = parseFloat("98.6"); // temperature = 98.6

// Works with scientific notation
let scientific: number = parseFloat("1.23e-4"); // scientific = 0.000123

// Handles leading/trailing whitespace
let trimmed: number = parseFloat("  3.14  "); // trimmed = 3.14

Compare with parseInt():

typescript
parseInt("3.14", 10);  // Returns 3 (integer only)
parseFloat("3.14");    // Returns 3.14 (preserves decimal)
4Use the unary plus operator for quick conversion

The unary plus (+) operator is a concise way to convert strings to numbers:

typescript
// Unary plus conversion
let value: number = +"123"; // value = 123

// Works with variables
const stringValue = "456";
let numValue: number = +stringValue; // numValue = 456

// Useful in inline expressions
const total: number = +price1 + +price2;

This is especially useful when working with form inputs:

typescript
// React example
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  const formData = new FormData(event.currentTarget);
  const age: number = +(formData.get("age") as string);
};

// Angular example
onSubmit() {
  const quantity: number = +this.form.value.quantity;
}
5Use union types when both types are valid

If your variable legitimately needs to handle both strings and numbers, use a union type instead of forcing conversion:

typescript
// Allow both types
let id: string | number;

id = "user-123";  // Valid
id = 123;         // Also valid

// Function accepting either type
function formatId(id: string | number): string {
  return `ID: ${id}`;
}

formatId("abc-123"); // Works
formatId(456);       // Also works

Use type guards when you need type-specific operations:

typescript
function processValue(value: string | number) {
  if (typeof value === "number") {
    // TypeScript knows value is number here
    return value.toFixed(2);
  } else {
    // TypeScript knows value is string here
    return value.toUpperCase();
  }
}
6Add validation for user inputs

When converting user-provided strings, always validate the result to handle invalid inputs gracefully:

typescript
function safeNumberConversion(input: string): number | null {
  const num = Number(input);

  // Check if conversion resulted in valid number
  if (isNaN(num)) {
    return null;
  }

  return num;
}

// Usage
const userInput = "123";
const result = safeNumberConversion(userInput);

if (result !== null) {
  console.log("Valid number:", result);
} else {
  console.error("Invalid number input");
}

For more complex validation, consider using a library like Zod:

typescript
import { z } from "zod";

const NumberSchema = z.string().transform((val) => {
  const num = Number(val);
  if (isNaN(num)) {
    throw new Error("Invalid number");
  }
  return num;
});

// Safe parsing
const parsed = NumberSchema.safeParse("123");
if (parsed.success) {
  const value: number = parsed.data; // TypeScript knows this is a number
}

Advanced notes

Type Coercion vs Explicit Conversion: While JavaScript allows implicit type coercion (e.g., "5" * 2 = 10), TypeScript requires explicit conversions for assignments. This prevents subtle bugs where coercion might produce unexpected results.

Performance Considerations: The unary plus operator (+) and Number() constructor have similar performance, while parseInt() and parseFloat() are slightly slower due to string parsing logic. For most applications, the performance difference is negligible—choose based on readability and requirements.

Handling Edge Cases: Be aware that Number("") returns 0, Number(null) returns 0, and Number(undefined) returns NaN. If you need stricter validation, check for these cases explicitly:

typescript
function strictNumberConversion(input: string): number {
  if (input.trim() === "") {
    throw new Error("Empty string is not a valid number");
  }
  const num = Number(input);
  if (isNaN(num)) {
    throw new Error(`Invalid number: ${input}`);
  }
  return num;
}

TypeScript Strict Mode: When using strictNullChecks, ensure your conversion functions account for potentially null or undefined inputs. Using the non-null assertion operator (!) bypasses TypeScript's safety checks and should be avoided unless you're absolutely certain the value exists.

Generic Type Conversion Function: For reusable type-safe conversions across your codebase, consider creating a generic converter:

typescript
function convertToNumber<T extends string | null | undefined>(
  value: T
): T extends null | undefined ? null : number {
  if (value == null) return null as any;
  const num = Number(value);
  if (isNaN(num)) throw new Error(`Cannot convert "${value}" to number`);
  return num as any;
}

Frequently asked questions

What does "Type 'string' is not assignable to type 'number'" mean?
This error is TypeScript's way of enforcing type safety during compile time. When you declare a variable, parameter, or property with a specific type (in this case, number), TypeScript ensures that only values of that type can be assigned to it. The error "Type 'string' is not assignable to type 'number'" indicates that you're trying to assign a string value where TypeScript expects a number.
How do I fix "Type 'string' is not assignable to type 'number'"?
This TypeScript error occurs when attempting to assign a string value to a variable, property, or parameter that expects a number type. TypeScript's static type checking prevents this at compile time to avoid runtime type errors.
What causes "Type 'string' is not assignable to type 'number'"?
Attempting to assign a string value directly to a number-typed variable without conversion Reading values from HTML input elements, which always return strings via .value property Parsing data from URL query parameters or route parameters, which are strings by default
Is the "Type 'string' is not assignable to type 'number'" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading