函数式 TypeScript:将 Postgres 数据库结果转换为视图模型 (FP-TS) 的管道中出错

functional typescript: error in pipeline converting postgres database results to a view model (fp-ts)

提问人:user1790300 提问时间:8/30/2023 更新时间:9/13/2023 访问量:118

问:

我正在尝试从 postgresql 数据库中检索数据,将其转换为视图模型数组并将数据返回给客户端,在这种情况下最好是作为单个对象而不是数组。对于我在错误消息下方列出的代码,我收到以下错误。我是函数式编程领域的新手,对如何利用数据转换概念感到困惑?

TS2345:“(department: {}) => (department: QueryResult) => Department”类型的参数不能分配给“(a: {}) => TaskEither<DBError, {}>”类型的参数。类型“(department: QueryResult) => Department”不能分配给类型“TaskEither<DBError, {}>”。

type DBError = MultipleResultsError | NoRecordsFoundError | Error;

const retrieveDepartments = async ({departmentId}: {departmentId: number}): Promise<TE.TaskEither<DBError, Department[]>> => {
    const client = await pool.connect();

    try {
        const query = 'SELECT * FROM department where departmentId = ?';
        const res: QueryResult<Department> = await client.query(query, [departmentId]);

        return pipe(
            TE.right(res.rows),
            TE.chain(
                TE.traverseArray(department => mapDepartmentViewModel)
            )
        );
    } catch (e) {
        return TE.left(e);
    } finally {
        client.release();
    }
}

export type Department = {
    departmentId: number,
    departmentName: string,
    departmentSupervisorId: number,
    departmentSupervisorFirstName: string,
    departmentSupervisorLastName: string
}

export const mapDepartmentViewModel = (department: QueryResult): Department => ({
    departmentId: department.departmentId,
    departmentName: department.departmentName,
    departmentSupervisorId: department.departmentSupervisorId,
    departmentSupervisorFirstName: department.departmentSupervisorFirstName,
    departmentSupervisorLastName: department.departmentSupervisorLastName
});
节点.js TypeScript 函数式编程 FP-TS

评论


答:

0赞 Vivick 9/7/2023 #1

TaskEither<T, E>只是 的类型别名。Task<Either<T, E>>

Task<T>是 的类型别名。() => Promise<T>

retrieveDepartments实际上返回 a,因为所有返回值都是 s。因此,应将其返回类型更改为 。Promise<Either<DBError, Department[]>>EitherPromise<Either<DBError, Department[]>>

请注意,它本身不能被类型化为一个,因为它需要一个参数,并且不接受:类型化为任务,用户将无法传递它实际期望的参数。retrieveDepartmentsTaskEither<DBError, Department[]>Task

评论

0赞 user1790300 9/8/2023
解决方案是什么?不知道你说的“......无法键入为 TaskEither<DBError, Department[]>因为它需要参数,而 Task 不带任何参数”。你能提供更清楚的信息吗?谢谢。
0赞 Vivick 9/8/2023
编辑了我的帖子。它将返回类型更改为 .作为用户,无法传递实际需要的参数。Promise<Either<DBError, Department[]>>TaskretrieveDepartments
0赞 DesignbyDC 9/9/2023 #2
type DBError = MultipleResultsError | NoRecordsFoundError | Error;

export type Department = {
    departmentId: number;
    departmentName: string;
    departmentSupervisorId: number;
    departmentSupervisorFirstName: string;
    departmentSupervisorLastName: string;
};

const retrieveDepartments = async ({
    departmentId,
}: { departmentId: number }): Promise<TE.TaskEither<DBError, Department[]>> => {
    const client = await pool.connect();

    try {
        const query = 'SELECT * FROM department where departmentId = ?';
        const res: QueryResult<Department> = await client.query(query, [departmentId]);

        return pipe(
            TE.right(res.rows),
            TE.chain((departments: Department[]) =>
                pipe(
                    TE.traverseArray(mapDepartmentViewModel)(departments),
                    TE.map((result: Department[]) => result)
                )
            )
        );
    } catch (e: DBError) {
        return TE.left(e);
    } finally {
        client.release();
    }
};

export const mapDepartmentViewModel = (
    department: QueryResult
): TE.TaskEither<DBError, Department> =>
    TE.tryCatch(
        () => {
            const mappedDepartment: Department = {
                departmentId: department.departmentId,
                departmentName: department.departmentName,
                departmentSupervisorId: department.departmentSupervisorId,
                departmentSupervisorFirstName: department.departmentSupervisorFirstName,
                departmentSupervisorLastName: department.departmentSupervisorLastName,
            };
            return mappedDepartment;
        },
        (error: DBError) => error
    );

评论

0赞 user1790300 9/12/2023
管道必须如何改变才能适应这种情况?
0赞 DesignbyDC 9/13/2023
我已经用完整的代码编辑了我的答案,还改进了函数内部的错误处理。我希望我能帮上忙。mapDepartmentViewModel