(Express、Node、Typescript、REST API)如何将函数从服务导入到控制器? 属性 ... 在类型 typeof 上不存在

(Express, Node, Typescript, REST API) How can I import a function from the service to the controllers? Property ... does not exist on type typeof

我应该如何在 Controller 中导入 loginMember?我正在开发 REST API,现在我需要在不同的文件位置使用代码。我在控制器中遇到错误。当我调用 loginMember 时。(找不到名称 'loginMember'.ts(2304))

服务

import MembersModel from '../models/MembersModel';
import BaseService from './BaseService';
import { createPasswordToHash } from '../scripts/utils/auth';
class MembersService extends BaseService {  
  constructor() {
    super(MembersModel);
  }

  // loginMember
  loginMember = async (email: any, password: any) => {
    return new Promise(async (resolve, reject) => {
      try {
        let data = await this.BaseModel.findOne({
          email: email,
          password: createPasswordToHash(password),
        });
        return resolve(data);
      } catch (error) {
        return reject(error);
      }
    });
  };
  
}

export default MembersService;

控制器

import BaseController from './BaseController';
import MembersService from '../services/MembersService';
import ApiError from '../errors/ApiError';
import { NextFunction, Request, Response } from 'express';
import { createPasswordToHash, generateAccessToken } from '../scripts/utils/auth';
import httpStatus from 'http-status';

class MembersController extends BaseController {
  constructor(membersService: MembersService) {
    super(membersService);    
  }

login = (req: Request, res: Response, next: NextFunction) => {
  MembersService.loginMember(req.body)
    .then((response: any) => {
      if (response) {
        const member = {
          ...response.toObject(),
          accessToken: generateAccessToken(response.toObject()),
        };
        delete member.password;
        delete member.createdAt;
        delete member.updatedAt;
        return res.status(httpStatus.OK).send(member);
      }
      return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
    })
    .catch((err: { message: string }) => {
      return next(
        new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
      );
    });
};
  
}
export default new MembersController(new MembersService());

现在我收到新错误:"属性 'loginMember' 在类型 'typeof MembersService'.ts(2339)"[ 上不存在=14=]

您正试图将 loginMember 称为 static method,但它并未定义为一个。您必须使用 MembersService 的实例才能使用该方法。由于您的 MembersController 已经使用 MembersService 实例进行了初始化,您可能只想在 MembersController 上使用 membersService 属性。此外,loginMember 方法接受电子邮件和密码,因此您必须显式传递这些参数,而不仅仅是传递请求正文。 (虽然我不确定电子邮件和密码在请求正文中的什么位置,所以我无法在那里帮助你。)所以通过这些更改,它看起来像:

class MembersController extends BaseController {
  private membersService: MembersService;

  constructor(membersService: MembersService) {
    super(membersService);
    this.membersService = membersService;
  }

login = (req: Request, res: Response, next: NextFunction) => {
  this.membersService.loginMember(email, password) // <- Get these from the request
    .then((response: any) => {
      if (response) {
        const member = {
          ...response.toObject(),
          accessToken: generateAccessToken(response.toObject()),
        };
        delete member.password;
        delete member.createdAt;
        delete member.updatedAt;
        return res.status(httpStatus.OK).send(member);
      }
      return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
    })
    .catch((err: { message: string }) => {
      return next(
        new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
      );
    });
};

另一个代码风格建议是在 login 方法中使用 async await 而不是 .then。此外,loginMember 方法中的 Promise 包装看起来没有必要,使用异步函数作为参数是 。以下应该在避免这些陷阱的同时完成工作:

  loginMember = (email: any, password: any): Promise<Response> => {
    return this.BaseModel.findOne({
      email: email,
      password: createPasswordToHash(password),
    });
  };