如何防止打字稿抱怨属性未定义

时间:2019-11-20 03:44:24

标签: node.js typescript express interface

我正在编写一个expressjs / typescript后端API。我正在使用辅助功能(用在装饰器中)来检查身份验证数据。它接受IMyRequest数据并进行一些检查,并将其返回为IMyAuthenticatedRequest

但是由于某种原因,打字稿仍然抱怨req函数的返回语句中的authenticate参数,即使我测试(并抛出错误),req.user可能仍未定义它是。如何防止此错误?

这是错误:

Type 'IMyRequest' is not assignable to type 'IMyAuthenticatedRequest'.
Types of property 'user' are incompatible.
Type 'IUserRequestData | undefined' is not assignable to type 'IUserRequestData'.
Type 'undefined' is not assignable to type 'IUserRequestData'.

这是打字稿所抱怨的示例代码(关于倒数第二行的return语句):

import { Request, Response } from 'express';

interface IUserRequestData {
  id: number;
  firstName: string;
  lastName: string;
  company: {
    id: number;
    name: string;
  };
}

interface IAuthenticatedHeaders {
  authorization: string;
  [x: string]: any;
}

interface IMyRequest extends Request {
  user?: IUserRequestData;
  correlationId?: any;
}

interface IMyAuthenticatedRequest extends IMyRequest {
  user: IUserRequestData;
  headers: IAuthenticatedHeaders;
}

interface IAuthenticationResult {
  req: IMyAuthenticatedRequest;
  res: Response;
  user: IUserRequestData;
  authenticated: boolean;
  authorization: string;
}

export function authenticate(req: IMyRequest, res: Response): IAuthenticationResult {
  /**
   * Check the authorization information on the request object and return it.
   *
   * @param args
   */

  if (!req.user || !req.headers || !req.headers.authorization) {
    throw new Error('Authentication error');
  }

  const { authorization } = req.headers;

  return { req, res, authorization, user: req.user, authenticated: true };
}

1 个答案:

答案 0 :(得分:0)

您可以使用类型保护功能

import { Request, Response } from "express";

interface IUserRequestData {
  id: number;
  firstName: string;
  lastName: string;
  company: {
    id: number;
    name: string;
  };
}

interface IAuthenticatedHeaders {
  authorization: string;
  [x: string]: any;
}

interface IMyRequest extends Request {
  user?: IUserRequestData;
  correlationId?: any;
}

interface IMyAuthenticatedRequest extends IMyRequest {
  user: IUserRequestData;
  headers: IAuthenticatedHeaders;
}

interface IAuthenticationResult {
  req: IMyAuthenticatedRequest;
  res: Response;
  user: IUserRequestData;
  authenticated: boolean;
  authorization: string;
}

export function authenticate(
  req: IMyRequest,
  res: Response
): IAuthenticationResult {
  /**
   * Check the authorization information on the request object and return it.
   *
   * @param args
   */

  isAthenticationRequest(req);

  const { authorization } = req.headers;

  return { req, res, authorization, user: req.user, authenticated: true };
}

function isAthenticationRequest(
  req: IMyAuthenticatedRequest | IMyRequest
): asserts req is IMyAuthenticatedRequest {
  if (!req.user || !req.headers || !req.headers.authorization) {
    throw new Error("Authentication error");
  }
}