subscriptions.ts
本地来源:模版/template/raphael-starterkit-v1-main/analysis/07-类型定义/subscriptions.ts.md
订阅类型定义 (types/subscriptions.ts) 逐行分析
文件概述
这个文件定义了与订阅系统相关的 TypeScript 类型。它包含了产品层级、订阅状态、订阅状态检查等核心类型定义,是订阅管理系统的基础类型文件。
产品层级类型分析
export interface ProductTier {
name: string;
id: string;
productId: string;
priceMonthly: string;
description: string;
featured: boolean;
features?: string[];
creditAmount?: number;
discountCode?: string;
}
基础信息字段
name: 产品层级名称(如"基础版"、"专业版"、"企业版")id: 产品层级的唯一标识符productId: 关联的产品IDdescription: 产品层级描述
价格信息
priceMonthly: 月度价格(字符串格式,可能包含货币符号)featured: 是否为推荐产品层级(用于UI突出显示)
可选功能字段
features?: 功能特性列表(可选)creditAmount?: 包含的积分数量(可选)discountCode?: 优惠码(可选)
设计说明
- 使用可选属性(
?)提供灵活性 - 支持不同类型的产品层级配置
- 便于在前端展示产品对比
订阅状态类型分析
export type SubscriptionStatus = {
isSubscribed: boolean;
status: string | null;
willEndOn: Date | null;
isInGracePeriod: boolean;
daysLeft: number | null;
};
订阅状态字段
isSubscribed: 是否已订阅(核心状态标识)status: 订阅状态字符串(可能为null)willEndOn: 订阅结束日期(Date对象或null)isInGracePeriod: 是否处于宽限期daysLeft: 剩余天数(可能为null)
设计模式
- 使用
boolean类型提供明确的状态判断 - 使用
Date对象处理时间计算 - 允许
null值处理未知状态
订阅状态枚举分析
export type SubscriptionState =
| "active"
| "trialing"
| "canceled"
| "past_due"
| "unpaid"
| "paused"
| "incomplete"
| "expired";
活跃状态
"active": 订阅活跃中"trialing": 试用期中
问题状态
"past_due": 逾期未付款"unpaid": 未付款"incomplete": 不完整状态
终止状态
"canceled": 已取消"expired": 已过期"paused": 已暂停
设计优势
- 使用字符串字面量类型提供类型安全
- 涵盖订阅的完整生命周期
- 便于状态机管理
状态检查常量分析
// Constants for subscription status checks
export const ACTIVE_STATUSES = ["active", "trialing"] as const;
export const GRACE_PERIOD_STATUSES = [
"canceled",
"past_due",
"unpaid",
"paused",
] as const;
有效状态常量
export const ACTIVE_STATUSES = ["active", "trialing"] as const;
- 定义直接有效的订阅状态
- 使用
as const确保类型推断精确 - 用于快速判断订阅是否有效
宽限期状态常量
export const GRACE_PERIOD_STATUSES = [
"canceled",
"past_due",
"unpaid",
"paused",
] as const;
- 定义宽限期状态
- 这些状态在特定条件下仍可能有效
- 需要结合到期时间进行判断
设计模式
- 使用
as const创建只读数组 - 提供类型安全的常量集合
- 便于在业务逻辑中使用
类型关系分析
状态管理流程
ProductTier -> 选择产品层级
↓
SubscriptionState -> 订阅状态变化
↓
SubscriptionStatus -> 计算最终状态
常量使用场景
// 检查订阅是否有效
function isActiveSubscription(state: SubscriptionState): boolean {
return ACTIVE_STATUSES.includes(state as any);
}
// 检查是否在宽限期
function isInGracePeriod(state: SubscriptionState): boolean {
return GRACE_PERIOD_STATUSES.includes(state as any);
}
设计模式分析
类型安全模式
- 使用联合类型限制可能的值
- 提供编译时类型检查
- 防止运行时类型错误
可选属性模式
- 使用
?标记可选属性 - 提供灵活的数据结构
- 支持渐进式数据填充
常量模式
- 使用
as const创建不可变常量 - 提供类型安全的枚举值
- 支持类型推断
状态机模式
- 明确定义状态转换
- 支持复杂的业务逻辑
- 便于状态管理
最佳实践总结
- 类型安全:使用联合类型和字面量类型
- 可扩展性:使用可选属性支持扩展
- 一致性:统一的命名规范
- 可读性:清晰的类型定义和注释
- 维护性:集中管理相关类型
- 性能:使用常量避免重复计算
- 业务逻辑:类型定义反映业务模型
使用示例
// 定义产品层级
const productTiers: ProductTier[] = [
{
name: "基础版",
id: "basic",
productId: "prod_basic",
priceMonthly: "¥99",
description: "适合个人用户",
featured: false,
features: ["基础功能", "邮件支持"],
creditAmount: 1000,
},
{
name: "专业版",
id: "pro",
productId: "prod_pro",
priceMonthly: "¥299",
description: "适合专业用户",
featured: true,
features: ["高级功能", "优先支持", "API访问"],
creditAmount: 5000,
},
];
// 检查订阅状态
function checkSubscriptionStatus(
state: SubscriptionState,
endDate: Date
): SubscriptionStatus {
const now = new Date();
const isActive = ACTIVE_STATUSES.includes(state as any);
const isInGrace = GRACE_PERIOD_STATUSES.includes(state as any) && endDate > now;
return {
isSubscribed: isActive || isInGrace,
status: state,
willEndOn: endDate,
isInGracePeriod: isInGrace,
daysLeft: Math.ceil((endDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)),
};
}
这个类型定义文件为订阅系统提供了完整的类型安全保障,确保了数据结构的一致性和业务逻辑的正确性。它是构建可靠订阅管理系统的基础。
本文档为站内渲染。原始文件本地路径:saas/source/templates/模版-template-raphael-starterkit-v1-main-analysis-07-类型定义-subs-419488.md(仅本地保留,不入库不部署)