JS 方法链接控制流程

JS Method Chaining Controlling Flow

我在 Typescript 中创建了一个方法,它利用方法链来创建一个简单的 sql 查询生成器。它实现了基本的查询方法。我想做的是不允许有人调用偏移方法,例如,如果他们之前没有调用 limit 或调用 where 两次。我知道我可以通过一个存储以前调用的方法的映射来实现一些东西,但我想知道是否有一个干净的解决方案来解决这个问题。我当前的查询生成器方法是

public qb = () =>
{
    let query = this.SELECT;
    const api = {
        where: (key: string, value: number|string) =>
        {
            query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
            return api;
        },
        and: (key: string, value: number|string) =>
        {
            query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
            return api;
        },
        orderBy: (key: string, order: 'ASC'|'DESC') =>
        {
            query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
            return api;
        },
        limit: (limit: number) =>
        {
            query = sql`${query} LIMIT ${limit}`;
            return api;
        },
        offset: (offset: number) =>
        {
            query = sql`${query} OFFSET ${offset}`;
            return api;
        },
        get: async () => this.rowMapper(await this.database.query(query)),
    };
    return api;
};

是否有强制方法链流动的好方法?

我最终采用的解决方案是创建多个内部具有不同方法的对象。该解决方案不是最干净的,但我找不到更好的解决方案

public qb = () =>
{
    let query = this.SELECT;

    const get = async () => this.rowMapper(await this.database.query(query));
    const limit = (_limit: number) =>
    {
        query = sql`${query} LIMIT ${_limit}`;
        return {
            offset: (offset: number) =>
            {
                query = sql`${query} OFFSET ${offset}`;
                return { get };
            },
            get,
        };
    };

    const api2 = {
        and: (key: string, value: number|string) =>
        {
            query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
            return api2;
        },
        orderBy: (key: string, order: 'ASC'|'DESC') =>
        {
            query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
            return {
                limit,
                get,
            };
        },
        limit,
        get,
    };
    const api = {
        where: (key: string, value: number|string) =>
        {
            query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
            return api2;
        },

    };
    return api;
};