В разных странах разная длина телефонных номеров. И я предлагаю сохранить список кодов стран вместо пользовательских регулярных выражений. Его легче поддерживать, и он более читабелен. Итак, решение:
- парсинг номера телефона
- , если он действителен, проверьте код страны
- , если он действителен, перейдите к следующему встроенному декоратору
Итак, я создал свой собственный декоратор с libphonenumber-js
Использование в DTO:
export class PhoneDto {
@ToPhone
@IsString({ message: 'must be a valid number' })
readonly phone!: string;
}
Реализация:
import { Transform } from 'class-transformer';
import { parsePhoneNumberFromString } from 'libphonenumber-js';
const validCountries = ['US', 'UK'];
export const ToPhone = Transform(
(value: any) => {
if (typeof value !== 'string') return undefined;
const parsed = parsePhoneNumberFromString(value);
if (!parsed) return undefined;
if (!validCountries.includes(parsed.country)) return undefined;
return parsed.number;
},
{ toClassOnly: true },
);
И да, это решение добавляет еще одну библиотеку, она может быть медленнее (на самом деле это зависит от списка ваших стран) из-за синтаксического анализа, но, как я уже говорил ранее, она более читабельна и удобна в обслуживании.