FP_TS - Property 'value' does not exist on type 'None'

35 Views Asked by At

While trying to transpile my codebase I keep receiving an error on the controller, "Property 'value' does not exist on type 'None'.". I am using typescript version 5.3.2 and fp-ts 2.16.2. This error message is confusing as Option in fp-ts, as this is a discriminated union between None and Some. None and Some both have a value "_value" property. What am I missing here? What is a way to fix this. I thought this was the intent of discriminated unions.

Repository function:
const verifyUser = (userId: string): TaskEither<ErrorBase, Option<User>> => tryCatch(
    async () => {
        const queryString = `
            SELECT "passwordCode" FROM ”User" WHERE "userId" = $1
          `;

        const result = await pool.query(queryString, [userId]);
        return result && result?.rows?.length > 0 ? some(result?.rows[0]) : none;
    },
    (reason: any) => (
        {message: reason.message, name: reason.name, details: ''}
    )
);

interactor function:
const verify = (userId: string): TaskEither<ErrorBase, Option<User>> => {
    const validator = validateFields;
    const dbOperation = repository.verifyUser;

    return pipe(
        userId,
        validateFields,
        chain(dbOperation)
    );
};

controller function:
postVerify: (req, res, next) => {
    const {userId} = req?.user as User || null;
    const interactorOperation = interactor.verify;

    pipe(
        userId,
        interactorOperation,
        fold(
            (error: ErrorBase) => async () => {
                next({ name: error.name, message: error.message, details: error.details });
            },
            (user: Option<User>) => async () => {
                if (user._tag === "None") {
                    next({ name: 'User verification failed.', message: 'User verification failed.', details: '' })
                }

error line -->    if (user.value) {
                    res.status(200).send({
                        userId: user.value.userId,
                        emailAddress: user.value.emailAddress,
                        firstName: user.value.firstName,
                        lastName: user.value.lastName
                    });
                } else {
                    next({ name: "SystemError", message: "An error occurred.  Please try again later.", details: "An error occurred.  Please try again later."});
                }
            }
        )
    )();
}

Update:

I tried the following but am receiving a different error:

E.match(
    (error: ErrorBase) => async () => {
        next({ name: error.name, message: error.message, details: error.details });
    },
    O.match(
        () => next({ name: 'User verification failed.', message: 'User verification failed.', details: '' }),
        (userObj: User) => {
            res.status(200).send({
                userId: userObj.userId,
                emailAddress: userObj.emailAddress,
                firstName: userObj.firstName,
                lastName: userObj.lastName
            });
        }
    )
)

This seems cleaner but I am getting the following error:
Argument of type '(ma: Option<User>) => void' is not assignable to parameter of type '(a: Option<User>) => () => Promise<void>'.
  Type 'void' is not assignable to type '() => Promise<void>'.

284                 O.match(
                    ~~~~~~~~
285                     () => next({ name: 'User verification failed.', message: 'User verification failed.', details: '' }),
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... 
295                     }
    ~~~~~~~~~~~~~~~~~~~~~
296                 )
    ~~~~~~~~~~~~~~~~~
0

There are 0 best solutions below