Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
Type guard that checks whether a value is a CallData instance. Provides TypeScript type narrowing.
Signature
function is(value: unknown): value is CallDataType
CallData.is(value: unknown): value is CallDataType
Parameters
- value - Value to check (any type)
Returns
boolean - true if value is CallData instance (with type narrowing)
Examples
Basic Usage
Type Narrowing
Array Filtering
import { CallData, type CallDataType } from '@tevm/voltaire';
const value: unknown = someFunction();
if (CallData.is(value)) {
// value is CallDataType here (type narrowed)
const selector = CallData.getSelector(value);
console.log(selector);
}
import { CallData, type CallDataType } from '@tevm/voltaire';
function process(input: string | CallDataType) {
if (CallData.is(input)) {
// input is CallDataType
console.log("Size:", input.length);
const selector = CallData.getSelector(input);
} else {
// input is string
const calldata = CallData(input);
}
}
import { CallData, type CallDataType } from '@tevm/voltaire';
const mixed: unknown[] = [
CallData("0xa9059cbb"),
"not calldata",
CallData.fromBytes(new Uint8Array([0x12, 0x34, 0x56, 0x78])),
123,
];
const calldata: CallDataType[] = mixed.filter(CallData.is);
console.log("Found", calldata.length, "calldata instances");
Type Narrowing
TypeScript narrows the type when is() returns true:
import { CallData, type CallDataType } from '@tevm/voltaire';
function handle(value: unknown) {
// Before: value is unknown
console.log(value.length); // ❌ Type error
if (CallData.is(value)) {
// After: value is CallDataType
console.log(value.length); // ✅ OK
console.log(CallData.toHex(value)); // ✅ OK
}
}
Comparison with isValid
is() - Type Guard
isValid() - Validation
import { CallData, type CallDataType } from '@tevm/voltaire';
function process(value: unknown) {
if (CallData.is(value)) {
// value is CallDataType (type narrowed)
return CallData.toHex(value); // Direct use
}
}
Checks: Already constructed CallData instance
Returns: Type guard (value is CallDataType)
Use for: Type narrowing, checking existing instancesimport { CallData } from '@tevm/voltaire';
function process(value: unknown) {
if (CallData.isValid(value)) {
// value is still unknown (no narrowing)
const calldata = CallData(value); // Must construct
return CallData.toHex(calldata);
}
}
Checks: Can be converted to CallData
Returns: Simple boolean
Use for: Input validation, pre-construction checks
Use Cases
Function Overloads
import { CallData, type CallDataType } from '@tevm/voltaire';
function processData(data: string): CallDataType;
function processData(data: CallDataType): CallDataType;
function processData(data: string | CallDataType): CallDataType {
if (CallData.is(data)) {
return data; // Already CallData
} else {
return CallData(data); // Convert from string
}
}
Union Type Handling
import { CallData, type CallDataType, type Bytecode } from '@tevm/voltaire';
function analyze(data: CallDataType | Bytecode) {
if (CallData.is(data)) {
// Handle as calldata
const selector = CallData.getSelector(data);
console.log("Function call:", selector);
} else {
// Handle as bytecode
console.log("Contract code:", Bytecode.toHex(data));
}
}
Generic Functions
import { CallData, type CallDataType } from '@tevm/voltaire';
function logIfCallData<T>(value: T): T {
if (CallData.is(value)) {
console.log("CallData:", CallData.toHex(value));
}
return value;
}
// Usage
const result = logIfCallData(someValue); // Type preserved
Type-Safe Caching
import { CallData, type CallDataType } from '@tevm/voltaire';
class Cache<T> {
private data = new Map<string, T>();
set(key: unknown, value: T): void {
if (CallData.is(key)) {
this.data.set(CallData.toHex(key), value);
} else {
throw new Error("Key must be CallData");
}
}
get(key: unknown): T | undefined {
if (CallData.is(key)) {
return this.data.get(CallData.toHex(key));
}
return undefined;
}
}
Implementation
Checks for CallData brand:
// Simplified implementation
import { brand } from './brand.js';
export function is(value: unknown): value is CallDataType {
return (
value instanceof Uint8Array &&
(value as any)[brand] === "CallData" &&
value.length >= 4
);
}
Checks:
- Is Uint8Array
- Has CallData brand
- Minimum 4 bytes (selector)
Very fast (just property checks):
// Benchmark: 10M iterations
const calldata = CallData("0xa9059cbb");
const notCalldata = "0xa9059cbb";
console.time("is (calldata)");
for (let i = 0; i < 10_000_000; i++) {
CallData.is(calldata);
}
console.timeEnd("is (calldata)");
// ~80ms
console.time("is (not calldata)");
for (let i = 0; i < 10_000_000; i++) {
CallData.is(notCalldata);
}
console.timeEnd("is (not calldata)");
// ~30ms (fails fast)
Type Safety Example
import { CallData, type CallDataType } from '@tevm/voltaire';
// Function that requires CallData
function process(data: CallDataType) {
return CallData.decode(data, abi);
}
// Safe wrapper with type guard
function safeProcess(data: unknown) {
if (!CallData.is(data)) {
throw new Error("Expected CallData");
}
return process(data); // Type-safe
}
Branded Type Pattern
CallData uses Symbol branding for type safety:
import { brand } from './brand.js';
// Type definition
export type CallDataType = Uint8Array & {
readonly [brand]: "CallData";
};
// Runtime check
export function is(value: unknown): value is CallDataType {
return (
value instanceof Uint8Array &&
(value as any)[brand] === "CallData"
);
}
This prevents accidental mixing of Uint8Arrays with CallData.