Specialized handling for numbers that exceed JavaScript's Number.MAX_SAFE_INTEGER and MIN_SAFE_INTEGER limits. The NumberValue class maintains full precision by storing numbers as strings while providing conversion utilities for different numeric representations.
A class for storing DynamoDB numbers that exceed the scale of JavaScript's safe integer limits or require decimal precision beyond JavaScript's capabilities.
/**
* Class for storing DynamoDB numbers that exceed the scale of
* JavaScript's MAX_SAFE_INTEGER and MIN_SAFE_INTEGER, or the
* decimal precision limit.
*
* This class does not support mathematical operations in JavaScript.
* Convert the contained string value to your application-specific
* large number implementation to perform mathematical operations.
*/
class NumberValue {
/** The precise number stored as a string */
readonly value: string;
/**
* Creates a new NumberValue instance
* @param value - A precise number as string, BigInt, number, or AttributeValue
*/
constructor(value: number | Number | BigInt | string | { N: string });
/**
* Static factory method for creating NumberValue instances
* @param value - A precise number as string, BigInt, number, or AttributeValue
*/
static from(value: number | Number | BigInt | string | { N: string }): NumberValue;
/**
* Converts to DynamoDB AttributeValue format
* @returns The AttributeValue form for DynamoDB
*/
toAttributeValue(): { N: string };
/**
* Converts to BigInt representation
* @returns BigInt representation
* @throws SyntaxError if the string representation is not convertable to a BigInt
*/
toBigInt(): bigint;
/**
* Returns string representation (canonical format in DynamoDB)
* @returns String representation
*/
toString(): string;
/**
* Returns the string value (same as toString)
* @returns String representation
*/
valueOf(): string;
}NumberValue can be created from various numeric types while preserving precision:
import { NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
// From string (recommended for precision)
const precise = new NumberValue("12345678901234567890.123456789");
console.log(precise.value); // "12345678901234567890.123456789"
// From BigInt
const fromBigInt = new NumberValue(12345678901234567890n);
console.log(fromBigInt.value); // "12345678901234567890"
// From regular number (safe integers only)
const fromNumber = new NumberValue(42);
console.log(fromNumber.value); // "42"
// From DynamoDB AttributeValue
const fromAttr = new NumberValue({ N: "999.999" });
console.log(fromAttr.value); // "999.999"
// Using static factory method
const factoryCreated = NumberValue.from("123.456");
console.log(factoryCreated.value); // "123.456"NumberValue provides methods to convert to different numeric representations:
import { NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
const num = new NumberValue("12345678901234567890");
// Convert to DynamoDB format
const attrValue = num.toAttributeValue();
console.log(attrValue); // { N: "12345678901234567890" }
// Convert to BigInt (for integers)
const bigInt = num.toBigInt();
console.log(bigInt); // 12345678901234567890n
// Get string representation
const str = num.toString();
console.log(str); // "12345678901234567890"
// valueOf() returns string (not number)
const val = num.valueOf();
console.log(val); // "12345678901234567890"NumberValue integrates seamlessly with the marshalling functions:
import { marshall, unmarshall, NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
// Marshall NumberValue instances
const data = {
id: "item-1",
preciseNumber: new NumberValue("12345678901234567890.123456789"),
regularNumber: 42,
};
const marshalled = marshall(data);
console.log(marshalled);
// {
// id: { S: "item-1" },
// preciseNumber: { N: "12345678901234567890.123456789" },
// regularNumber: { N: "42" }
// }
// Unmarshall with number wrapping
const dynamoRecord = {
id: { S: "item-1" },
largeNumber: { N: "12345678901234567890" },
decimal: { N: "123.456" },
regularNumber: { N: "42" },
};
const unwrapped = unmarshall(dynamoRecord, { wrapNumbers: true });
console.log(unwrapped);
// {
// id: "item-1",
// largeNumber: NumberValue { value: "12345678901234567890" },
// decimal: NumberValue { value: "123.456" },
// regularNumber: NumberValue { value: "42" }
// }NumberValue constructor validates input to prevent precision loss:
import { NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
// Safe numbers work fine
const safe = new NumberValue(42); // OK
const safeBig = new NumberValue(Number.MAX_SAFE_INTEGER); // OK
// Imprecise numbers throw errors
try {
new NumberValue(Number.MAX_SAFE_INTEGER + 1); // Throws error
} catch (error) {
console.error(error.message); // "NumberValue should not be initialized with an imprecise number"
}
try {
new NumberValue(NaN); // Throws error
} catch (error) {
console.error(error.message); // "NumberValue should not be initialized with an imprecise number"
}
try {
new NumberValue(Infinity); // Throws error
} catch (error) {
console.error(error.message); // "NumberValue should not be initialized with an imprecise number"
}
// Use strings for precision
const precise = new NumberValue("12345678901234567890.123456789"); // OKThe toBigInt() method can throw errors for non-integer values:
import { NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
const integer = new NumberValue("12345678901234567890");
const decimal = new NumberValue("123.456");
// Integer conversion works
const bigInt = integer.toBigInt(); // 12345678901234567890n
// Decimal conversion throws
try {
decimal.toBigInt(); // Throws SyntaxError
} catch (error) {
console.error(error.message); // "Cannot convert 123.456 to a BigInt"
}Use NumberValue with custom conversion functions for application-specific number handling:
import { unmarshall, NumberValueImpl as NumberValue } from "@aws-sdk/util-dynamodb";
const record = {
price: { N: "19.99" },
quantity: { N: "1000000000000000000" },
};
// Custom conversion function
const result = unmarshall(record, {
wrapNumbers: (numString) => {
// Use decimal.js or similar for precise decimals
if (numString.includes('.')) {
return parseFloat(numString); // or use Decimal library
}
// Use BigInt for large integers
return BigInt(numString);
}
});
console.log(result);
// { price: 19.99, quantity: 1000000000000000000n }