知识库首页 模版 subscriptions.ts.md

subscriptions.ts

本地来源:模版/模版文档对比说明/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: 关联的产品ID
  • description: 产品层级描述

价格信息

  • 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 创建不可变常量
  • 提供类型安全的枚举值
  • 支持类型推断

状态机模式

  • 明确定义状态转换
  • 支持复杂的业务逻辑
  • 便于状态管理

最佳实践总结

  1. 类型安全:使用联合类型和字面量类型
  2. 可扩展性:使用可选属性支持扩展
  3. 一致性:统一的命名规范
  4. 可读性:清晰的类型定义和注释
  5. 维护性:集中管理相关类型
  6. 性能:使用常量避免重复计算
  7. 业务逻辑:类型定义反映业务模型

使用示例

// 定义产品层级
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/模版-模版文档对比说明-07-类型定义-subscriptions-ts-fe40d6.md(仅本地保留,不入库不部署)