如何在TypeScript中避免运行时字符串与数字相加的问题?
b + c in TypeScript Absolutely, even though TypeScript's type information gets erased when compiled to JavaScript, we can still prevent this kind of runtime bug with intentional runtime checks paired with TS's compile-time safeguards. Here are the key practical strategies:
1. Use Custom Type Guards for Explicit Runtime Checks
Type guards let you narrow down a value's type at runtime while keeping TypeScript's compile-time validation in sync. You can write a simple guard to validate if a value is a proper number (including checking for NaN, since typeof NaN still returns number):
function isNumber(value: unknown): value is number { return typeof value === 'number' && !isNaN(value); } // Assume b and c come from runtime inputs (e.g., API responses, user input) const b: unknown = fetchRuntimeValue('b'); const c: unknown = fetchRuntimeValue('c'); // Validate before calculation if (!isNumber(b) || !isNumber(c)) { throw new TypeError('Both b and c must be valid numbers'); } // Now TS confirms b/c are numbers at compile time, and runtime checks enforce it let a: number = b + c;
This catches invalid types early, before they cause unexpected string concatenation (like '5' + 3 resulting in '53' instead of 8).
2. Leverage Schema Validation Libraries
Writing manual checks for every input gets repetitive. Libraries like zod or io-ts let you define a type schema once, then automatically generate runtime validation logic that aligns perfectly with TypeScript's compile-time types.
For example, using Zod:
import { z } from 'zod'; // Define a schema for valid numbers const NumberSchema = z.number(); // Validate runtime inputs (throws an error if invalid) const validatedB = NumberSchema.parse(fetchRuntimeValue('b')); const validatedC = NumberSchema.parse(fetchRuntimeValue('c')); // TS infers validatedB/validatedC as number, runtime ensures no mismatches let a: number = validatedB + validatedC;
These libraries handle edge cases (like NaN, Infinity, or string inputs) out of the box, and keep your type definitions DRY.
3. Enforce Input Types at the Source
Whenever possible, block invalid values from reaching your TypeScript code in the first place:
- For API responses, use parsers that validate the structure and types of incoming data.
- For user input, add frontend validation (e.g., HTML number inputs, input masks) to reduce invalid values from being submitted.
This reduces the need for heavy runtime checks later in your codebase.
Key Takeaway
TypeScript's strength is compile-time safety, but it can't replace runtime validation for external inputs. The solution is to pair TS's compile-time type checks with explicit runtime validation to catch type mismatches before they cause bugs.
内容的提问来源于stack exchange,提问作者ashish singh

