

在前端开发中,掌握一些实用的代码效率技巧可以大大提升我们的开发效率。本文将重点介绍两个非常实用的技巧:TypeScript 类型复用技巧和正则表达式在前端的高频应用场景。
TypeScript 的类型系统非常强大,合理运用类型复用技巧可以让我们的代码更加简洁、可维护。
// 基础用户类型
interface User {
id: number;
name: string;
email: string;
password: string;
avatar: string;
createdAt: Date;
updatedAt: Date;
}
// 用户列表展示只需要部分字段
type UserListItem = Pick<User, 'id' | 'name' | 'avatar'>;
// 用户注册时不需要某些字段
type UserRegisterRequest = Omit<User, 'id' | 'createdAt' | 'updatedAt'>;// 可选更新类型
type UpdateUserRequest = Partial<Omit<User, 'id' | 'email'>>;
// 必填字段验证
type RequiredUserFields = Required<Pick<User, 'name' | 'email' | 'password'>>;// 用户角色权限映射
type UserRole = 'admin' | 'editor' | 'viewer';
type Permission = 'read' | 'write' | 'delete';
type RolePermissions = Record<UserRole, Permission[]>;
const rolePermissions: RolePermissions = {
admin: ['read', 'write', 'delete'],
editor: ['read', 'write'],
viewer: ['read']
};// API 响应统一格式
type ApiResponse<T> = {
code: number;
message: string;
data: T;
timestamp: number;
};
// 分页响应格式
type PaginatedResponse<T> = {
items: T[];
total: number;
page: number;
pageSize: number;
hasNext: boolean;
};
// 使用示例
type UserListResponse = ApiResponse<PaginatedResponse<User>>;// 事件名称类型
type EventName = `on${Capitalize<string>}`;
// CSS 属性类型
type Size = 'sm' | 'md' | 'lg';
type SizeClass = `btn-${Size}`;
// 使用示例
const buttonSizes: Record<Size, SizeClass> = {
sm: 'btn-sm',
md: 'btn-md',
lg: 'btn-lg'
};正则表达式是前端开发中的利器,掌握常见的应用场景可以让我们事半功倍。
// 邮箱验证
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// 手机号验证(中国大陆)
const phoneRegex = /^1[3-9]\d{9}$/;
// 密码强度验证
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/;
// 身份证号码验证
const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/;
// URL 验证
const urlRegex = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/;// 提取字符串中的数字
function extractNumbers(str: string): number[] {
const matches = str.match(/\d+/g);
return matches ? matches.map(Number) : [];
}
// 移除 HTML 标签
function removeHtmlTags(html: string): string {
return html.replace(/<[^>]*>/g, '');
}
// 提取 URL 中的参数
function extractUrlParams(url: string): Record<string, string> {
const params: Record<string, string> = {};
const matches = url.match(/[?&]([^=]+)=([^&]*)/g);
if (matches) {
matches.forEach(match => {
const [, key, value] = match.match(/[?&]([^=]+)=([^&]*)/) || [];
if (key && value) {
params[decodeURIComponent(key)] = decodeURIComponent(value);
}
});
}
return params;
}// 手机号格式化
function formatPhoneNumber(phone: string): string {
return phone.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
}
// 千分位格式化
function formatNumber(num: number): string {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
// 银行卡号格式化
function formatBankCard(cardNumber: string): string {
return cardNumber.replace(/(\d{4})(?=\d)/g, '$1 ');
}
// 驼峰命名转换
function toCamelCase(str: string): string {
return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
}
// 下划线命名转换
function toSnakeCase(str: string): string {
return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
}// 身份证号脱敏
function maskIdCard(idCard: string): string {
return idCard.replace(/(\d{4})\d{10}(\w{4})/, '$1**********$2');
}
// 手机号脱敏
function maskPhoneNumber(phone: string): string {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
// 银行卡号脱敏
function maskBankCard(cardNumber: string): string {
return cardNumber.replace(/\d(?=\d{4})/g, '*');
}
// 姓名脱敏
function maskName(name: string): string {
if (name.length <= 2) {
return name.charAt(0) + '*';
}
return name.charAt(0) + '*'.repeat(name.length - 2) + name.charAt(name.length - 1);
}// 提取 CSS 中的颜色值
function extractColors(css: string): string[] {
const colorRegex = /#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})\b|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)/g;
const matches = css.match(colorRegex);
return matches || [];
}
// 验证变量名是否符合规范
function isValidVariableName(name: string): boolean {
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
}
// 提取注释内容
function extractComments(code: string): string[] {
const commentRegex = /\/\*[\s\S]*?\*\/|\/\/.*$/gm;
const matches = code.match(commentRegex);
return matches ? matches.map(comment => comment.replace(/^\/\*\s*|\s*\*\/|\/\/\s*/g, '')) : [];
}让我们结合 TypeScript 和正则表达式,创建一个完整的用户注册表单验证示例:
interface ValidationRule {
pattern: RegExp;
message: string;
}
interface ValidationRules {
[key: string]: ValidationRule[];
}
class FormValidator {
private rules: ValidationRules = {
username: [
{
pattern: /^[a-zA-Z0-9_]{3,20}$/,
message: '用户名必须是3-20个字符,只能包含字母、数字和下划线'
}
],
email: [
{
pattern: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: '请输入有效的邮箱地址'
}
],
phone: [
{
pattern: /^1[3-9]\d{9}$/,
message: '请输入有效的手机号码'
}
],
password: [
{
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/,
message: '密码必须至少8位,包含大小写字母和数字'
}
],
idCard: [
{
pattern: /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/,
message: '请输入有效的身份证号码'
}
]
};
validate(field: string, value: string): string[] {
const errors: string[] = [];
const fieldRules = this.rules[field];
if (!fieldRules) {
return errors;
}
for (const rule of fieldRules) {
if (!rule.pattern.test(value)) {
errors.push(rule.message);
}
}
return errors;
}
validateForm(formData: Record<string, string>): Record<string, string[]> {
const errors: Record<string, string[]> = {};
for (const [field, value] of Object.entries(formData)) {
const fieldErrors = this.validate(field, value);
if (fieldErrors.length > 0) {
errors[field] = fieldErrors;
}
}
return errors;
}
}
// 使用示例
const validator = new FormValidator();
// 单个字段验证
const emailErrors = validator.validate('email', 'invalid-email');
console.log(emailErrors); // ['请输入有效的邮箱地址']
// 整个表单验证
const formData = {
username: 'user123',
email: 'user@example.com',
phone: '13800138000',
password: 'Password123',
idCard: '11010519900307283X'
};
const errors = validator.validateForm(formData);
console.log(errors); // 空对象表示验证通过// 不好的做法:在循环中重复创建正则表达式
function validateEmails(emails: string[]): boolean[] {
return emails.map(email => /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email));
}
// 好的做法:复用正则表达式实例
const EMAIL_REGEX = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
function validateEmails(emails: string[]): boolean[] {
return emails.map(email => EMAIL_REGEX.test(email));
}// 创建通用的工具类型
namespace Types {
export type Nullable<T> = T | null;
export type Optional<T> = T | undefined;
export type Maybe<T> = T | null | undefined;
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
}
// 使用示例
interface UserProfile {
id: number;
name: string;
settings: {
theme: string;
notifications: boolean;
};
}
type OptionalUserProfile = Types.Optional<UserProfile>;
type DeepPartialUserProfile = Types.DeepPartial<UserProfile>;掌握 TypeScript 类型复用技巧和正则表达式的高效应用,可以显著提升前端开发效率。通过合理使用类型工具,我们可以构建更加类型安全、易于维护的应用。而熟练运用正则表达式,则能够优雅地处理各种字符串处理任务。
在实际开发中,建议:
希望这些技巧能够帮助大家在日常开发中更加高效!