Skip to content

Validate a phone number

isValid is the verdict. isPossibleWithReason weighs the calling code and the length while leaving the digits alone, which lets an incomplete number pass. getValidationError names the exact fault behind a failed isValid, carrying the numbers that describe it.

An unfinished number comes back TOO_SHORT. A number whose digits belong to no assigned range still comes back IS_POSSIBLE, because the check never reads them.

import { parsePhoneNumber } from '@telixon/core';
function reason(input: string) {
return parsePhoneNumber(input, { defaultRegion: 'US' }).isPossibleWithReason();
}
reason('+1 415'); // 'TOO_SHORT'
reason('+999 123'); // 'INVALID_CALLING_CODE'
reason('+1 21255512345678'); // 'TOO_LONG'
reason('+1 999 555 0132'); // 'IS_POSSIBLE', while isValid() is false

The six reason codes are under PossibilityResult.

getValidationError returns null for a valid number. Otherwise it returns one of nine kinds, each carrying the numbers behind the fault:

import { parsePhoneNumber, type ValidationError } from '@telixon/core';
function describe(error: ValidationError): string {
switch (error.kind) {
case 'EMPTY':
return 'Enter a phone number.';
case 'INVALID_CALLING_CODE':
return 'No country uses this calling code.';
case 'TOO_SHORT':
return `Too short. Use at least ${error.minLength} digits.`;
case 'TOO_LONG':
return `Too long. Use at most ${error.maxLength} digits.`;
case 'INVALID_LENGTH':
return `Wrong length. Valid lengths are ${error.possibleLengths.join(', ')}.`;
case 'POSSIBLE_LOCAL_ONLY':
return 'Add the area code.';
case 'PATTERN_MISMATCH':
return 'This number does not exist in this region.';
case 'NATIONAL_PREFIX_MISSING':
return `Start the number with ${error.expectedPrefix}.`;
case 'NATIONAL_PREFIX_PRESENT':
return `Remove the leading ${error.prefix}.`;
}
}
const number = parsePhoneNumber('+1 415');
if (!number.isValid()) {
describe(number.getValidationError()!); // 'Too short. Use at least 10 digits.'
}

The error answers for the value as it stands, which means a half-typed number reports TOO_SHORT the same way a finished wrong one does.

To restrict validity to a single region at parse time, use strict.

formatE164 produces the canonical string. It parses back with no options:

parsePhoneNumber('(415) 555-0132', { defaultRegion: 'US' }).formatE164(); // '+14155550132'
parsePhoneNumber('+14155550132').isValid(); // true