(반년만에 두번째 글이 나와서 민망 ... )
A -> B -> C -> D
interface UserRecord {
id: number;
nickname: string;
state: string;
property?: Prisma.JsonValue;
createdAt?: Date;
updatedAt?: Date;
}
async function getUser(userId: number): Promise<UserRecord | null> {
try {
return await prismaClient.users.findFirstOrThrow({ where: { id: userId } });
} catch (error) {
return null;
}
}
const user = await getUser(1);
(IO 에서 에러 발생하기 위해 의도적으로 orThrow 사용)
...
function getUserNickname(user: UserRecord) {
return user.nickname;
}
...
const user = await getUser(userId);
if (!user) {
return null;
}
return getUserNickname(user);
...
async function getUserByNickname(nickname: string): Promise<UserRecord | null> {
try {
return await prismaClient.users.findFirstOrThrow({ where: { nickname } });
} catch (error) {
return null;
}
}
const user = await getUser(userId);
if (!user) {
return null;
}
const nickName = getUserNickname(user);
const targetUser = await getUserByNickname(nickName);
if (!targetUser) {
return null;
}
return targetUser;
(억지로 만든 상황을 감안해야한다 ... )
import * as E from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/function';
import * as TE from 'fp-ts/lib/TaskEither';
function getUserTE(userId: number) {
return TE.tryCatch(
() => {
return prismaClient.users.findFirstOrThrow({ where: { id: userId } });
},
() => new Error(`no user data ${userId}`),
);
}
function getUserByNicknameTE(nickname: string) {
return TE.tryCatch(() => {
return prismaClient.users.findFirstOrThrow({ where: { nickname } });
}, E.toError);
}
...
const getUser = pipe(
userId,
getUserTE,
TE.map(getUserNickname),
TE.chain((nickName) => getUserByNicknameTE(nickName)),
);
const userTask = await getUser();
const result = pipe(
userTask,
E.getOrElseW((error) => error),
);
function getUserTE(userId: number) {
return TE.tryCatch(
() => {
return prismaClient.users.findFirstOrThrow({ where: { id: userId } });
},
() => new Error(`no user data ${userId}`),
);
}
async function getUserE(userId: number): Promise<E.Either<Error, UserRecord>> {
try {
const user = await prismaClient.users.findFirstOrThrow({
where: { id: userId },
});
return E.right(user);
} catch (error) {
return E.left(error);
}
}
// const user: E.Either<Error, UserRecord>
const user = await getUserE(1);
// const userTE: E.Either<Error, UserRecord>
const userTE = await getUserTE(1)();
// Type 'Promise<Either<Error, UserRecord>>' is not assignable to type // 'Either<unknown, UserRecord>'
const user = await pipe(1, getUserE, E.map(getNickname));