提问人:user1790300 提问时间:8/30/2023 更新时间:9/13/2023 访问量:118
函数式 TypeScript:将 Postgres 数据库结果转换为视图模型 (FP-TS) 的管道中出错
functional typescript: error in pipeline converting postgres database results to a view model (fp-ts)
问:
我正在尝试从 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
});
答:
0赞
Vivick
9/7/2023
#1
TaskEither<T, E>
只是 的类型别名。Task<Either<T, E>>
Task<T>
是 的类型别名。() => Promise<T>
retrieveDepartments
实际上返回 a,因为所有返回值都是 s。因此,应将其返回类型更改为 。Promise<Either<DBError, Department[]>>
Either
Promise<Either<DBError, Department[]>>
请注意,它本身不能被类型化为一个,因为它需要一个参数,并且不接受:类型化为任务,用户将无法传递它实际期望的参数。retrieveDepartments
TaskEither<DBError, Department[]>
Task
评论
0赞
user1790300
9/8/2023
解决方案是什么?不知道你说的“......无法键入为 TaskEither<DBError, Department[]>因为它需要参数,而 Task 不带任何参数”。你能提供更清楚的信息吗?谢谢。
0赞
Vivick
9/8/2023
编辑了我的帖子。它将返回类型更改为 .作为用户,无法传递实际需要的参数。Promise<Either<DBError, Department[]>>
Task
retrieveDepartments
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
评论