Регулярные выражения – это мощные инструменты для сопоставления с образцом и манипулирования текстом. В TypeScript регулярные выражения можно использовать не только для операций во время выполнения, но также для проверки типов и обеспечения безопасности типов. В этой статье мы рассмотрим различные методы использования регулярных выражений в типах TypeScript, попутно предоставляя примеры кода и практические применения.
- Использование литеральных типов регулярных выражений.
Один простой способ включить регулярные выражения в типы TypeScript — использовать литеральные типы регулярных выражений. Присвоив шаблон регулярного выражения переменной или свойству, мы можем обеспечить проверку типов на основе этого шаблона. Например:
type EmailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
type User = {
email: string & EmailRegex;
};
const user: User = {
email: 'example@example.com', // Valid
};
const invalidUser: User = {
email: 'invalid-email', // Error: Type 'string' is not assignable to type 'string & EmailRegex'
};
- Использование условных типов.
Условные типы TypeScript позволяют нам создавать динамические типы на основе определенных условий. Мы можем использовать эту функцию для выполнения условных проверок типов с помощью регулярных выражений. Например:
type StringMatching<T extends string, P extends RegExp> = T extends P ? T : never;
type Email = StringMatching<string, /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/>;
const validEmail: Email = 'example@example.com'; // Valid
const invalidEmail: Email = 'invalid-email'; // Error: Type '"invalid-email"' is not assignable to type 'Email'
- Использование защиты типа:
Защита типа позволяет нам сузить тип переменной на основе условия. Используя регулярные выражения в средствах защиты типов, мы можем выполнять проверку и уточнение типов во время выполнения. Вот пример:
function isEmail(value: unknown): value is string {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value as string);
}
function processEmail(email: unknown) {
if (isEmail(email)) {
// email is now narrowed down to type 'string'
// Perform operations specific to email
} else {
// Handle invalid email case
}
}
- Использование сопоставленных типов.
Сопоставленные типы позволяют нам преобразовывать свойства существующего типа в новый тип. Мы можем комбинировать регулярные выражения с сопоставленными типами для создания сложных преобразований типов. Рассмотрим следующий пример:
type CamelCase<T> = T extends `${infer P1}_${infer P2}`
? `${Lowercase<P1>}${Uppercase<P2> extends '_' | Uppercase<P2> ? CamelCase<P2> : Uppercase<P2>}`
: Lowercase<T>;
type SnakeCase<T> = T extends `${infer P1}${infer P2}`
? `${Lowercase<P1> extends Uppercase<P1> ? '_' : ''}${Lowercase<P1>}${SnakeCase<P2>}`
: '';
type Person = {
first_name: string;
last_name: string;
};
type CamelCasePerson = {
[K in keyof Person as CamelCase<K>]: Person[K];
};
type SnakeCasePerson = {
[K in keyof Person as SnakeCase<K>]: Person[K];
};
const person: CamelCasePerson = {
firstName: 'John',
lastName: 'Doe',
};
const snakeCasePerson: SnakeCasePerson = {
first_name: 'John',
last_name: 'Doe',
};
Используя возможности регулярных выражений в типах TypeScript, мы можем добиться повышенной безопасности типов, применять ограничения на основе шаблонов и выполнять динамические уточнения типов. Мы исследовали различные методы, в том числе литеральные типы регулярных выражений, условные типы, средства защиты типов и сопоставленные типы, для включения регулярных выражений в систему типов TypeScript. Понимание и использование этих методов позволит вам писать более надежный и типобезопасный код в ваших проектах TypeScript.