无论我尝试什么,打字稿对象都可能未定义

typescript object possibly undefined no matter what I tried

我正在使用 canvas 捕捉裁剪后的图像。这是函数

export const getCroppedImg = (
  image: HTMLImageElement,
  crop: Crop,
  fileName: string
): Promise<Blob> => {
  let canvas: HTMLCanvasElement;
  let ctx: CanvasRenderingContext2D;
  // I m using next.js
  if (typeof window !== "undefined") {
    if (crop) {
      canvas = document.createElement("canvas");
      const scaleX = image.naturalWidth / image.width;
      const scaleY = image.naturalHeight / image.height;
      canvas.width  =crop.width ? crop.width * scaleX : undefined;
      canvas.height =crop.height &&  crop.height * scaleY;
      ctx = canvas.getContext("2d") as CanvasRenderingContext2D;

      ctx.drawImage(
        image,
        crop.x * scaleX,
        crop.y * scaleY,
        crop.width * scaleX,
        crop.height * scaleY,
        0,
        0,
        crop.width * scaleX,
        crop.height * scaleY
      );
    }
  }

crop.x, crop.y, crop.width crop.height 导致 ts 错误“对象可能是 'undefined'”。我用 if(crop) 包装了整个逻辑,我尝试了两种不同的方法

      canvas.width  =crop.width ? crop.width * scaleX : undefined;
      canvas.height =crop.height &&  crop.height * scaleY;

"canvas.width" 和 "canvas.height" 警告说

"Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.ts(2322)

这是作物:

import { Crop } from "react-image-crop";

interface Crop {
        aspect?: number;
        x?: number;
        y?: number;
        width?: number;
        height?: number;
        unit?: 'px' | '%';
    }
    
                

您在这一行中说 canvas.width 可能未定义:

canvas.width  =crop.width ? crop.width * scaleX : undefined;

所以你可以重新处理逻辑,这样就不是这样了。 话虽这么说,有时您会比 TypeScript 编译器了解更多,因此如果您知道在需要访问该值时永远不会未定义,则可以断言该值。

canvas.width as number

为什么在裁剪界面上使用可选字段?

你试过了吗?:

interface Crop {
    aspect: number;
    x: number;
    y: number;
    width: number;
    height: number;
    unit: 'px' | '%';
}

将已有的crop.widthcrop.height取出到各自的变量中再检查。

您也不能将 undefined 分配给 canvas.width,或使用 && 有条件地为身高分配一个值 - 请改用 if

如果任何 crop 属性未定义(您将无法绘制 canvas 或使用 drawImage 正确),因此在这种情况下尽早抛出错误或 return。

您也没有 returnPromise,因此删除 Promise<Blob> 类型。

export const getCroppedImg = (
    image: HTMLImageElement,
    crop: Crop,
) => {
    const { width, height, x, y } = crop;
    if (typeof window === "undefined" || !width || !height || !x || !y) {
        // Proceeding further would make no sense;
        // can't adjust canvas, or draw the image
        // return here, or throw an error or something
        throw new Error('Bad argument');
    }
    const canvas = document.createElement("canvas");
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;

    canvas.width = width * scaleX;
    canvas.height = height * scaleY;
    const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;

    ctx.drawImage(
        image,
        x * scaleX,
        y * scaleY,
        width * scaleX,
        height * scaleY,
        0,
        0,
        width * scaleX,
        height * scaleY
    );
}