TypeScript에서 문자열을 숫자로 변환하려면 Number(text)를 호출합니다. 결과의 타입은 number이고, 텍스트가 올바른 숫자가 아니면 값은 NaN입니다. "42px"처럼 뒤에 문자가 붙은 텍스트에는 parseInt(text, 10)이나 parseFloat(text)를 쓰세요.
네 가지 변환은 모두 number 타입을 반환합니다. TypeScript는 텍스트가 올바른지 알지 못합니다. 잘못된 문자열도 number를 돌려주며, 그 값이 NaN일 뿐입니다.
왜 변환해야 하나
폼 필드, URL 매개변수, 환경 변수, 파일 내용은 문자열로 들어옵니다. TypeScript는 숫자가 필요한 자리에 문자열을 쓰지 못하게 합니다.
index.ts(3,23): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
문자열에 -, *, / 산술 연산을 하면 오류입니다. +는 허용되지만 문자열을 이어 붙이므로 "3" + 10은 문자열 "310"이 됩니다. 그래서 변환을 먼저 해야 합니다: Number(quantity) * 10.
타입 단언도 도움이 되지 않습니다. quantity as number는 거부되고(TS2352), as unknown as number로 억지로 통과시켜도 컴파일러를 조용히 시킬 뿐 런타임의 값은 여전히 문자열입니다.
Number, parseInt, parseFloat, 단항 플러스 비교
네 함수는 깔끔한 입력에서는 결과가 같고, 그 밖의 경우에는 모두 다릅니다. 이 표는 Node에서 각 함수를 실제로 실행한 결과입니다.
| 입력 | Number(s) | +s | parseInt(s, 10) | parseFloat(s) |
|---|---|---|---|---|
"42" | 42 | 42 | 42 | 42 |
"3.99" | 3.99 | 3.99 | 3 | 3.99 |
"42px" | NaN | NaN | 42 | 42 |
"" | 0 | 0 | NaN | NaN |
" 3 " | 3 | 3 | 3 | 3 |
"1e3" | 1000 | 1000 | 1 | 1000 |
"0x1F" | 31 | 31 | 0 | 0 |
"1,000" | NaN | NaN | 1 | 1 |
"12_000" | NaN | NaN | 12 | 12 |
"abc" | NaN | NaN | NaN | NaN |
표 뒤에 있는 규칙은 다음과 같습니다.
Number와 단항+는 동일합니다. 공백을 제거한 뒤 문자열 전체를 변환하고,1e3과0x16진수를 이해하며, 남는 문자가 있으면NaN을 반환합니다. 빈 문자열이나 공백만 있는 문자열은0이 됩니다.parseInt와parseFloat는 앞에서부터 읽다가 쓸 수 없는 첫 문자에서 멈추므로"42px"와"1,000"은 일부만 숫자가 됩니다. 빈 문자열은NaN입니다.parseInt는 소수 부분을 버리고 지수를 이해하지 못합니다."1e3"은e에서 멈춥니다.- 숫자 구분자(
12_000)는 소스 코드에서는 유효하지만 문자열에서는 아닙니다.
입력을 검증할 때는 Number가 더 엄격한 선택입니다. parseInt와 parseFloat는 CSS 크기처럼 실제로 단위나 접미사가 붙은 텍스트에 알맞습니다.
잘못된 입력 처리: NaN
NaN의 타입은 number이므로 컴파일러는 아무 경고도 하지 않습니다. Number.isNaN이나 Number.isFinite로 결과를 직접 확인하세요.
number | undefined를 반환하면 실패가 타입의 일부가 되므로, 모든 호출부가 산술 연산 전에 이를 처리해야 합니다. Number.isFinite는 Infinity도 걸러 내는데, Number("Infinity")는 아무렇지 않게 이 값을 반환합니다.
전역 isNaN(x)는 피하세요. 인수를 먼저 변환하므로 JavaScript에서 isNaN("abc")는 true입니다. TypeScript의 선언은 number만 받으므로 문자열을 넘기면 TS2345 오류가 나는데, 이미 변환된 값에 Number.isNaN을 쓰라는 신호입니다.
문자열을 정수로
parseInt에는 항상 두 번째 인수인 기수(radix)를 넘기세요. 10진수 텍스트라면 10입니다. 선택 사항이지만 의도를 드러내고, 다른 진법에서는 결과에 영향을 줍니다. 소수 문자열에서 정수를 얻으려면 변환한 뒤 명시적으로 반올림합니다.
parseInt는 문자열을 기대합니다. parseInt(12.7)은 컴파일 오류(TS2345)인데, 이는 유용합니다. JavaScript에서 숫자에 parseInt를 쓰면 먼저 텍스트로 변환하므로 0.0000005 같은 값에서 틀린 답(5)을 내기 때문입니다. 숫자에는 Math.trunc를 쓰세요. Number.MAX_SAFE_INTEGER를 넘는 정수는 BigInt(text)가 값 전체를 파싱합니다(잘못된 텍스트에는 NaN을 반환하지 않고 SyntaxError를 던집니다).
숫자를 문자열로
String(n), n.toString(), `${n}` 중 무엇을 써도 숫자를 가장 짧은 문자열 형태로 변환합니다. 서식 메서드를 쓰면 더 세밀하게 제어할 수 있습니다.
toFixed는 입력한 10진수가 아니라 2진수 값을 반올림하므로 (1.005).toFixed(2)는 "1.00"입니다. 1.005는 1.005보다 조금 작은 값으로 저장되기 때문입니다. 금액은 정수 단위(센트 등)로 보관하거나 Intl.NumberFormat으로 서식을 지정하세요.
String(n)은 null과 undefined에도 동작하지만("null", "undefined"가 됩니다), n.toString()은 값이 없을 수 있으므로 strict에서 컴파일 오류가 됩니다.
빠른 참조
| 작업 | 코드 | 결과 타입 |
|---|---|---|
| 문자열을 숫자로(엄격) | Number(s) 또는 +s | number(NaN일 수 있음) |
| 텍스트 앞부분의 정수 | parseInt(s, 10) | number(NaN일 수 있음) |
| 텍스트 앞부분의 소수 | parseFloat(s) | number(NaN일 수 있음) |
| 결과 확인 | Number.isFinite(n), Number.isNaN(n) | boolean |
| 큰 정수 | BigInt(s) | bigint |
| 숫자를 문자열로 | String(n), n.toString(), `${n}` | string |
| 소수점 자릿수 고정 | n.toFixed(2) | string |
| 다른 진법 | n.toString(16) | string |
| 천 단위 구분 기호 | n.toLocaleString("en-US") | string |
자주 묻는 질문
TypeScript에서 문자열을 숫자로 변환하려면 어떻게 하나요?
Number(text)를 씁니다. number를 반환하는데, 올바른 숫자 텍스트면 그 값을, 그 밖에는 NaN을, 빈 문자열이나 공백만 있는 문자열이면 0을 반환합니다. "42px"처럼 뒤에 다른 문자가 붙을 수 있는 텍스트라면 parseInt(text, 10)이나 parseFloat(text)를 쓰세요.
as number로 문자열을 숫자로 캐스팅할 수 있나요?
as number로 문자열을 숫자로 캐스팅할 수 있나요?없습니다. "42" as number는 컴파일 오류(TS2352)이고, unknown을 거쳐 억지로 통과시켜도 단언(assertion)은 컴파일러가 보는 타입만 바꿉니다. 런타임의 값은 여전히 문자열 "42"입니다. Number(), parseInt(), parseFloat()로 값을 변환하세요.
TypeScript에서 Number()와 parseInt()의 차이는 무엇인가요?
Number는 문자열 전체를 변환하며 어느 부분이라도 숫자가 아니면 NaN을 반환하므로 Number("42px")는 NaN입니다. parseInt는 앞에서부터 숫자를 읽다가 처음 나오는 숫자가 아닌 문자에서 멈추므로 parseInt("42px", 10)은 42이고, 소수점 이하는 버립니다. Number("")는 0이지만 parseInt("")는 NaN입니다.
문자열이 올바른 숫자인지 어떻게 확인하나요?
변환한 뒤 결과를 검사합니다: const n = Number(text); if (text.trim() !== "" && Number.isFinite(n)) { ... }. Number("")가 0이므로 빈 문자열 검사가 중요합니다. 전역 isNaN이 아니라 Number.isNaN을 쓰세요. 어차피 TypeScript는 전역 isNaN에 number 인수만 허용합니다.
TypeScript에서 숫자를 문자열로 변환하려면 어떻게 하나요?
String(n), n.toString(), 템플릿 리터럴 `${n}` 모두 같은 결과를 냅니다. 소수점 자릿수를 고정하려면 n.toFixed(2), 다른 진법이면 n.toString(16), 천 단위 구분 기호가 필요하면 n.toLocaleString("en-US")를 씁니다.