I am trying to retrieve data from a postgresql database, transform it to a view model array and return the data to the client, ideally as a single object in this case rather than an array. I am getting the following error for the code I have listed beneath the error message. I am new to the functional programming space and am confused on how to utilize the data transformation concepts?
我正在尝试从PostgreSQL数据库检索数据,将其转换为视图模型数组,并将数据返回给客户端,在本例中最好是作为单个对象,而不是数组。对于我在错误消息下面列出的代码,我收到以下错误。我是函数式编程领域的新手,对如何利用数据转换概念感到困惑。
TS2345: Argument of type ‘(department: {}) => (department: QueryResult) => Department’ is not assignable to parameter of type '(a: {}) => TaskEither<DBError, {}>'. Type ‘(department: QueryResult) => Department’ is not assignable to type 'TaskEither<DBError, {}>'.
TS2345:‘(Department:{})=>(Department:QueryResult)=>Department’的参数不能赋给‘(a:{})=>TaskEther
’类型的参数。‘TaskEither
’类型‘(Department:QueryResult)=>Department’不可赋值。
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
});
更多回答
优秀答案推荐
TaskEither<T, E>
is just a type alias for Task<Either<T, E>>
.
TaskEther
只是TASK
>的类型别名。
Task<T>
is a type alias for () => Promise<T>
.
任务是()=>Promise
的类型别名。
retrieveDepartments
actually returns a Promise<Either<DBError, Department[]>>
since all the return values are Either
s. Therefore you should change its return type to Promise<Either<DBError, Department[]>>
.
因为所有返回值都是Other,所以RetriveDepartments实际上返回了一个Promise
>。因此,您应该将其返回类型更改为Promise<
>。
Note that retrieveDepartments
itself couldn't be typed as a TaskEither<DBError, Department[]>
since it requires an argument, and Task
take none: typed as a task, users won't be able to pass the arguments it actually expects.
请注意,receteDepartments本身不能被类型化为TaskEther
,因为它需要一个参数,而Task Take None:作为一个任务类型化,用户将无法传递它实际需要的参数。
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
);
更多回答
What would the solution be? Not sure what you mean by "...couldn't be typed as a TaskEither<DBError, Department[]> since it requires an argument, and Task take none". Could you provide more clarity? Thanks.
解决办法是什么?不知道你说的“...无法将其类型设置为TaskEither,因为它需要参数,而Task不接受任何参数”。你能提供更多的清晰度吗?谢谢.
Edited my post. It's changing the return type to Promise<Either<DBError, Department[]>>
. As a Task
users can't pass the arguments that retrieveDepartments
actually needs.
编辑了我的帖子。它正在将返回类型更改为Promise<>。作为一个任务,用户不能传递RetrieDepartments实际需要的参数。
How would the pipe have to change to accomodate this?
管道必须如何改变才能适应这种情况?
I´ve edited my answer with the complete code, improving also the error handling inside your mapDepartmentViewModel
function. I hope I was able to help.
我已经用完整的代码编辑了我的答案,还改进了mapDepartmentViewModel函数中的错误处理。我希望我能帮上忙。
我是一名优秀的程序员,十分优秀!