To convert a string to a double in TypeScript, pass it to Number() or parseFloat(). TypeScript has no separate double type; every number is already a 64-bit double, so "1299.99" becomes 1299.99:
const price: number = Number("1299.99"); // 1299.99
My test bench for this one: TypeScript 7.0.2 and Node.js v22.22.2, strict mode on, with each console result below copied from a real run.
Below you’ll find the three conversion options, how they treat messy input, a safe parser for form values, dollar amounts with commas, and the rounding traps that catch most people.
Does TypeScript have a double type?
No. Java and C# split decimals into float and double, but JavaScript has a single number type stored as an IEEE 754 double-precision value. TypeScript just describes that type, so “convert to double” really means “convert to number“.
That also means integers and decimals use the same conversion. If you’re working with whole numbers or want parseInt() details, my guide on how to convert a string to a number in TypeScript covers the general case.
Convert a string to a double with Number(), parseFloat() or +
All three return a number when the text is a clean decimal. The unary plus is just a shorter spelling of Number():
const priceText: string = "1299.99";
const a: number = Number(priceText);
const b: number = parseFloat(priceText);
const c: number = +priceText;
console.log(a, b, c);
console.log(typeof a, typeof b, typeof c);
console.log("with tax:", (a * 1.0825).toFixed(2));
Output:
1299.99 1299.99 1299.99
number number number
with tax: 1407.24
I reach for Number() by default because it says what it does, and a teammate scanning the code won’t miss it. A lone + is easy to overlook. Once you’ve got a number, formatting a number to 2 digits in TypeScript handles the display side.
Number() vs parseFloat(): how they handle messy strings
The difference shows up with real input. Number() needs the whole string to be numeric, while parseFloat() reads from the left and stops at the first character it can’t use:
const inputs: string[] = ["19.99", " 42.50 ", "12.5kg", "", "1,299.99", "1e3", "0x1F", ".5", "abc"];
console.log("input".padEnd(13), "Number()".padEnd(10), "parseFloat()");
for (const s of inputs) {
const label = JSON.stringify(s).padEnd(13);
console.log(label, String(Number(s)).padEnd(10), parseFloat(s));
}
Output:
input Number() parseFloat()
"19.99" 19.99 19.99
" 42.50 " 42.5 42.5
"12.5kg" NaN 12.5
"" 0 NaN
"1,299.99" NaN 1
"1e3" 1000 1000
"0x1F" 31 0
".5" 0.5 0.5
"abc" NaN NaN

parseFloat() quietly keeps 12.5 from “12.5kg” and 1 from “1,299.99”, while Number() turns an empty string into 0.Two results deserve a second look. Number("") is 0, so a blank form field can slip through as a real value. And parseFloat("1,299.99") gives 1, which is a silent and expensive bug on a price.
| Input | Number() / + | parseFloat() |
|---|---|---|
" 42.50 " | 42.5 (trims spaces) | 42.5 |
"12.5kg" | NaN | 12.5 |
"" | 0 | NaN |
"1,299.99" | NaN | 1 |
"0x1F" | 31 (hex) | 0 |
Use parseFloat() when you want the number at the start of text like “12.5kg”. Use Number() when the whole value must be numeric. Blank input is easier to spot after you check if a string is empty in TypeScript.
Why can’t I just assign or cast the string to number?
TypeScript’s types disappear at runtime, so the compiler won’t convert anything for you. Strict mode blocks the three shortcuts people try first:
const priceText: string = "19.99";
const price: number = priceText;
const doubled = priceText * 2;
const forced = priceText as number;
Output:
dbl_types.ts(3,7): error TS2322: Type 'string' is not assignable to type 'number'.
dbl_types.ts(4,17): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
dbl_types.ts(5,16): error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

string to number all fail to compile.The as number error matters most. Even if you force it with as unknown as number, the value is still the string “19.99” at runtime. Assertions only change what the compiler believes, as I explain in TypeScript type casting.
Safely convert user input to a double
Values from forms, query strings and APIs need checks. This helper trims the text, rejects blanks, and refuses NaN and Infinity by testing Number.isFinite():
function toDouble(input: string): number | null {
const text = input.trim();
if (text === "") return null; // Number("") would give 0
const value = Number(text);
return Number.isFinite(value) ? value : null;
}
const formValues: string[] = ["74.25", " 3.5 ", "", "12.5kg", "Infinity", "-0.75"];
for (const v of formValues) {
const result = toDouble(v);
console.log(JSON.stringify(v).padEnd(11), "->", result === null ? "rejected" : result);
}
const qty = toDouble("3");
if (qty !== null) {
console.log("narrowed to number:", (qty * 19.99).toFixed(2));
}
Output:
"74.25" -> 74.25
" 3.5 " -> 3.5
"" -> rejected
"12.5kg" -> rejected
"Infinity" -> rejected
"-0.75" -> -0.75
narrowed to number: 59.97
Returning number | null forces every caller to handle bad input, and the !== null check narrows the type back to number. That pattern is explained in TypeScript type narrowing, and there’s more on validation in checking if a string is a number in TypeScript.
Convert currency strings like “$1,299.99” to a double
US dollar amounts usually arrive with a dollar sign, thousands commas and stray spaces. Strip those first, then convert with Number() so anything unexpected still fails loudly:
function parseUsd(text: string): number {
const cleaned = text.replace(/[$,\s]/g, "");
const value = Number(cleaned);
if (cleaned === "" || !Number.isFinite(value)) {
throw new Error(`Not a dollar amount: "${text}"`);
}
return value;
}
const csvLine = "Austin TX;$1,299.99;$ 84.50;$12,450.00";
const [store, ...amounts] = csvLine.split(";");
const values = amounts.map(parseUsd);
console.log(store, values);
const total = values.reduce((sum, v) => sum + v, 0);
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
console.log("total:", usd.format(total));
try {
parseUsd("USD 10");
} catch (err) {
console.log((err as Error).message);
}
Output:
Austin TX [ 1299.99, 84.5, 12450 ]
total: $13,834.49
Not a dollar amount: "USD 10"

I throw here because a wrong price is worse than a crash in a batch job; in a UI you’d return null like the earlier helper. Adding up the parsed values works the same as the sum of an array in TypeScript.
Double precision and rounding after string conversion
Because every number is a binary double, some decimals can’t be stored exactly. Watch what happens, and note that toFixed() hands you a string, not a number:
const a = parseFloat("0.1");
const b = parseFloat("0.2");
console.log("0.1 + 0.2 =", a + b);
const rounded = (a + b).toFixed(2);
console.log("toFixed(2):", rounded, typeof rounded);
console.log("back to number:", Number(rounded), typeof Number(rounded));
const cents = Math.round(parseFloat("19.99") * 100) + Math.round(parseFloat("5.01") * 100);
console.log("cents:", cents, "->", (cents / 100).toFixed(2));
console.log("max safe:", Number.MAX_SAFE_INTEGER);
console.log("parsed :", Number("9007199254740993"));
console.log("bigint :", BigInt("9007199254740993"));
Output:
0.1 + 0.2 = 0.30000000000000004
toFixed(2): 0.30 string
back to number: 0.3 number
cents: 2500 -> 25.00
max safe: 9007199254740991
parsed : 9007199254740992
bigint : 9007199254740993n

0.1 + 0.2 isn’t exactly 0.3, toFixed(2) returns a string, and digits past 253 get lost.For money, convert to whole cents with Math.round(value * 100), add the cents, and divide only for display. Integers beyond Number.MAX_SAFE_INTEGER, such as long account IDs, belong in BigInt or stay strings.
Which string to double method should you use?
| Situation | Use | Why |
|---|---|---|
| Clean numeric text | Number(s) | Readable, rejects partial numbers |
| Number at the start, like “12.5kg” | parseFloat(s) | Stops at the first non-numeric character |
| Form or API input | toDouble() helper | Handles blanks, NaN and Infinity |
| Dollar amounts | Strip $ and commas, then Number() | parseFloat would stop at the comma |
If you’re cleaning up text before converting it, these guides help:
- Remove spaces from a string in TypeScript
- Check string length in TypeScript
- Compare strings in TypeScript
- Convert a number to a string with leading zeros
Frequently asked questions
Is there a double type in TypeScript?
No. TypeScript’s