属性 类型缺失,但在使用 Object.defineProperty 时需要类型

Property is missing in type but required in type when using Object.defineProperty

我有这个验证中间件,我正在尝试编写它来在发送请求时验证空负载:

const _isMissing = (body: any): boolean => !body;

export const isMissing = Object.defineProperty(_isMissing, '_apiGatewayResponse', {
  value: LAMBDA_400_RESPONSE,
});

interface ValidationFunction extends Function {
  _apiGatewayResponse: APIGatewayProxyResult;
}

export function validateRequestBody(
  handler: LambdaFunction,
  validations: Array<ValidationFunction>,
): LambdaFunction {
  const wrapper: LambdaFunction = async (
    event: APIGatewayEvent,
  ): Promise<APIGatewayProxyResult> => {
    const eventBody = event.body ? JSON.parse(event.body) : null;
    for (const validation of validations) {
      const invalidBody = validation(eventBody);
      if (invalidBody) {
        return validation._apiGatewayResponse || LAMBDA_400_RESPONSE;
      }
    }

    const response = await handler(event);
    return response;
  };

  return wrapper;
}

但是当我开始使用中间件功能时:

validateRequestBody(myPostFunction, [isMissing]);

我在 isMissing 上收到 TypeScript 错误,指出

Property '_apiGatewayResponse' is missing in type '(body: any) => boolean' but required in type 'ValidationFunction'.

谁能帮我解决这个问题?我真的找不到任何类似的问题,非常感谢任何帮助。

谢谢!

isMissing 的类型(来自 _isMissing)是 (body: any) => boolean(一个函数接受类型为 any 的单个参数并返回一个 boolean), 但 ValidationFunction 需要一个 _apiGatewayResponse 属性 就可以了。即使您通过 Object.defineProperty 在运行时添加 属性,也不会更改函数具有的编译时类型。

您可以通过无害的类型断言向 TypeScript 保证结果具有正确的类型,该类型断言仅断言您可以轻松看到代码正在添加的内容。例如:

type IsMissingFunction = ((body: any) => boolean) & ValidationFunction;

const _isMissing = (body: any): boolean => !body;

export const isMissing: IsMissingFunction = Object.defineProperty(
    _isMissing as typeof _isMissing & Pick<ValidationFunction, "_apiGatewayResponse">,
    '_apiGatewayResponse', {
        value: LAMBDA_400_RESPONSE
    }
);

Playground link

可以只使用as IsMissingFunction而不是更冗长的as typeof _isMissing & Pick<ValidationFunction, "_apiGatewayResponse">:

type IsMissingFunction = ((body: any) => boolean) & ValidationFunction;

const _isMissing = (body: any): boolean => !body;

export const isMissing: IsMissingFunction = Object.defineProperty(
    _isMissing as IsMissingFunction,
    '_apiGatewayResponse', {
        value: LAMBDA_400_RESPONSE
    }
);

我更喜欢第一个版本的原因是,如果您稍后编辑 IsMissingFunction(或 ValidationFunction)以添加更多属性,TypeScript 将在第一个示例中引发一个有用的错误,指示该函数不再符合 IsMissingFunction 的定义。对于第二个示例,您必须做出 真正 大的改变才能抱怨。