For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/index.md.
  • 繁體中文
  • ts-fsrs
    把間隔重複,組合成你需要的樣子。

    一個用於 TypeScript 的型別安全排程框架。從開箱即用的 FSRS-7 開始,再自由組合模型、時間系統與 middleware,無須切換到另一套 API。

    npm
    yarn
    pnpm
    bun
    deno
    npm install ts-fsrs
    import { 
    function DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7">(options?: DefaultSchedulerOptions<Version>): Promise<DefaultScheduler<Version>>
    type DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7"> = (Version extends "FSRS-7" ? Omit<SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<FSRS7DefaultSchedulerModel, Chrono<{
        readonly time: SRSSchema<{
            input: Date;
            output: Date;
        }>;
        readonly config: SRSSchema<{
            input: {
                readonly fractionalDays?: boolean | undefined;
            };
            output: {
                readonly fractionalDays: boolean;
            };
        }>;
        readonly fields: {
            readonly card: SRSSchema<{
                input: {
                    dueAt: Date;
                    lastReviewAt?: (Date | null) | undefined;
                };
                output: {
                    dueAt: Date;
                    lastReviewAt: Date | null;
                };
            }>;
            readonly revlog: SRSSchema<{
                input: {
                    dueAt: Date;
                    lastReviewAt?: (Date | null) | undefined;
                    reviewTime: Date;
                };
                output: {
                    dueAt: Date;
                    lastReviewAt: Date | null;
                    reviewTime: Date;
                };
            }>;
        };
    }>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>, "definition"> : Omit<...> & {
        ...;
    }) & {
        ...;
    }
    DefaultScheduler
    } from 'ts-fsrs'
    const createdAt = new Date('2026-01-01T00:00:00.000Z') export const now = new Date('2026-01-02T09:30:00.000Z') export const
    const scheduler: DefaultScheduler<"FSRS-7">
    scheduler
    = await
    DefaultScheduler<"FSRS-7">(options?: DefaultSchedulerOptions<"FSRS-7"> | undefined): Promise<DefaultScheduler<"FSRS-7">>
    DefaultScheduler
    ({
    DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.desiredRetention?: number | undefined
    desiredRetention
    : 0.9,
    }) export const
    const card: {
        cardId: string | number;
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reps: number;
        lapses: number;
        scheduledDays: number;
        learningStep: number;
        state: State;
        scheduleStatus: "review" | "new" | "learning";
    }
    card
    =
    const scheduler: DefaultScheduler<"FSRS-7">
    scheduler
    .
    newCard: (options?: ({
        readonly cardId?: string | number | undefined;
    } & {
        readonly now?: Date | undefined;
    }) | undefined) => {
        cardId: string | number;
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reps: number;
        lapses: number;
        scheduledDays: number;
        learningStep: number;
        state: State;
        scheduleStatus: "review" | "new" | "learning";
    }
    newCard
    ({
    cardId: 'landing-demo', now: createdAt, }) // One `{ grade, card, revlog }` row per grade — the panel renders exactly this. export const
    const outcomes: PreviewResult<{
        card: {
            cardId: string | number;
            stabilityFast: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reps: number;
            lapses: number;
            scheduledDays: number;
            learningStep: number;
            state: State;
            scheduleStatus: "review" | "new" | "learning";
        };
        revlog: {
            cardId: string | number;
            stabilityFast: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            scheduledDays: number;
            learningStep: number;
            reviewTime: Date;
            state: State;
            scheduleStatus: "review" | "new" | "learning";
            rating: Grade;
        };
    }>
    outcomes
    =
    const scheduler: DefaultScheduler<"FSRS-7">
    scheduler
    .
    preview: (input: {
        readonly card: Readonly<Omit<Readonly<{
            stabilityFast: number;
            stability: number;
            difficulty: number;
        } & {
            dueAt: Date;
            lastReviewAt: Date | null;
        } & {
            readonly cardId: string | number;
            readonly reps: number;
            readonly lapses: number;
            readonly scheduledDays: number;
            readonly learningStep?: number | undefined;
        } & SchedulerCoreFields$1<"review" | "new" | "learning">>, keyof SchedulerCoreFields$1<"review" | "new" | "learning">> & SchedulerCoreFields$1<"review" | "new" | "learning">>;
        readonly now?: Date | undefined;
    }) => PreviewResult<...>
    preview
    ({ card, now })
    穩定度
    3.9221
    難度
    3.5307
    stabilityFast
    3.13768

    內建型別安全

    同一份 Schema 同時負責執行階段驗證,以及 TypeScript 輸入與輸出型別推導。

    組合而無須遷移

    從預設排程器開始,在同一核心上逐步替換模型、時間系統與排程策略。

    以惰性求值為設計原則

    惰性預覽、依版本分割程式碼,以及支援 tree shaking 的子路徑匯出。

    漸進式 API

    從簡單開始,擴充時無須重來。

    直接使用預設 FSRS 排程器、組合自己的排程策略,或實作全新模型 — 全部共用同一核心。

    01

    使用

    DefaultScheduler 提供具備合理預設值的 FSRS 排程器,支援 FSRS-3 至 FSRS-7,預設使用 FSRS-7。DefaultScheduler

    02

    自訂

    選擇模型與時間系統,再逐一加入產品需要的 middleware 策略。defineScheduler.use(middleware)

    03

    擴充

    內建能力不足時,自行撰寫 middleware、時間系統或模型。defineMiddlewaredefineChrono

    排程核心

    型別安全

    一份契約,貫穿所有型別。

    Standard Schema 為設定、卡片、複習日誌、記憶狀態與時間值提供統一的執行階段驗證與型別契約。

    • 同一份 schema 同時負責執行階段驗證與 TypeScript 型別推導,兩者不會產生落差。
    • 輸入卡片維持 readonly,只有排程結果可變。
    • middleware 加入的欄位與狀態會自動出現在推導型別中。
    StandardSchemaV1zod
    Model
    Chrono
    Middleware
    Readonly<Card>輸入
    Mutable<Card>排程結果

    scheduleStatus: 'new' | 'review' | 'suspended'

    內建功能

    開箱即用,依需求組合。

    Stats

    為卡片加入並維護複習次數(reps)與遺忘次數(lapses)。

    DesiredRetention

    將設定的目標保留率傳入間隔計算。

    CostAdr

    依記憶狀態與複習成本調整保留率,用於取代固定目標保留率策略。

    Fuzzing

    以卡片 ID 與複習次數為種子,套用確定性的間隔變化。

    LearningSteps

    以分鐘、小時或天為單位安排學習與重新學習步驟。

    Leech

    每當卡片的遺忘次數達到設定閾值的整數倍時,就暫停該卡片。

    MaximumInterval

    將最終排程間隔限制在設定上限內。

    MonotonicInterval

    避免較高評分得到較短的排程間隔。

    ScheduledDays

    儲存排程天數及復原所需的舊值,啟用小數天數時保留小數間隔。

    架構

    選擇最符合需求的模型、時間系統與策略。

    各個元件彼此相容。

    模型

    • FSRS-3
    • FSRS-4
    • FSRS-4.5
    • FSRS-5
    • FSRS-6
    • FSRS-7
    • defineModel

    Chrono

    • dateChrono
    • numericChrono
    • temporalInstantChrono
    • defineChrono

    Middleware

    • learningSteps
    • desiredRetention
    • costAdr
    • fuzzing
    • leech
    • stats
    • defineMiddleware
    Scheduler CorenewCard · preview · review · rollback
    Card + Revlog + ScheduleStatus
    definition
    .use(fuzzing).use(learningSteps)

    use() 會回傳新的 definition;既有 definition 與由它建立的排程器都不會被改動。

    效能

    效能是架構的一部分。

    API 以惰性求值、程式碼分割與不可變結果為設計核心。

    依版本分割程式碼

    DefaultScheduler 會依需求載入指定的 FSRS 版本,避免初始載入未使用的模型程式碼。

    惰性 preview

    preview() 只會為實際迭代到的評分進行排程。

    惰性建立 schema

    排程器的 schema 會在第一次存取時才建立,而非在宣告時建立。

    支援 tree shaking 的匯出

    sideEffects 為 false,模型與 middleware 皆提供子路徑匯出。

    不可變結果

    review 會回傳新卡片,不會修改任何輸入。

    可回復的複習

    rollback() 可從 revlog 還原卡片先前的狀態,包括 middleware 欄位。

    貢獻者

    由開源貢獻者共同打造。

    專案中的模型、middleware 與各項改進,都受益於社群透過 Pull Request 提供的想法與貢獻。

    贊助者

    感謝每一份支持。

    每一份贊助都支持 ts-fsrs 的持續維護,以及與 FSRS 研究進展保持同步。

    目前贊助者

    • L-M-Sherlock

    過往贊助者

    • tomerbeil

    成為贊助者

    從 FSRS 開始,打造更進一步的系統。

    預設排程器可涵蓋常見情境;需要時,可以用不同的模型、時間系統與 middleware 組合自己的排程器。