Skip to content

Validate user input

A phone field needs two kinds of feedback: tolerant while the user types, exact on submit. The possibility checks give the first. getValidationError gives the second.

Most values in a field are unfinished, so treat a short number as neutral. Two failures are worth flagging immediately, because more typing cannot fix them: a calling code that does not exist and a number that is already too long.

function feedbackWhileTyping(input: string): string | null {
const number = parsePhoneNumber(input, { defaultRegion: 'US' });
if (number.isValid()) return null;
switch (number.isPossibleWithReason()) {
case 'INVALID_CALLING_CODE':
return 'That country code does not exist.';
case 'TOO_LONG':
return 'This number has too many digits.';
default:
return null;
}
}
feedbackWhileTyping('+1 415'); // null, still typing
feedbackWhileTyping('+999 123'); // 'That country code does not exist.'
feedbackWhileTyping('+1 21255512345678'); // 'This number has too many digits.'

The six reason codes are under PossibilityResult.

Require isValid and turn the failure into a message the user can act on. The carried payloads let each message name the fix:

import 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 'That country code does not exist.';
case 'TOO_SHORT':
return `Too short. This number needs ${error.minLength} digits.`;
case 'TOO_LONG':
return `Too long. This number takes at most ${error.maxLength} digits.`;
case 'INVALID_LENGTH':
return `Wrong length. Valid lengths are ${error.possibleLengths.join(', ')}.`;
case 'POSSIBLE_LOCAL_ONLY':
return 'That number only works when dialled locally.';
case 'PATTERN_MISMATCH':
return 'The length is right, but no number with these digits exists in this region.';
case 'NATIONAL_PREFIX_MISSING':
return `Start the number with ${error.expectedPrefix}.`;
case 'NATIONAL_PREFIX_PRESENT':
return `Drop the leading ${error.prefix}.`;
}
}
const number = parsePhoneNumber('+1 415');
if (!number.isValid()) {
describe(number.getValidationError()!); // 'Too short. This number needs 10 digits.'
}

Store the canonical E.164 string. It parses back with no options:

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

To restrict validity to the form’s own region at parse time, use strict.