объект машинописного текста, возможно, не определен, независимо от того, что я пытался

#typescript #canvas #next.js

Вопрос:

Я использую холст для захвата обрезанного изображения. вот функция

 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 amp;amp; 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 «Объект, возможно, «не определен»». Я обернул всю логику if(crop) , я попробовал два разных подхода

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

«холст.ширина» и «холст.высота» предупреждают, что

 "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' | '%';  }      

Ответ №1:

Извлеките существующие crop.width и crop.height в их собственные переменные, прежде чем проверять их.

Вы также не можете назначить undefined значение a canvas.width или использовать amp;amp; для условного присвоения значения высоте — используйте if вместо этого.

Не похоже, что следовать какой-либо логике имеет смысл, если какие-либо crop свойства не определены (вы не сможете правильно нарисовать холст или использовать drawImage его), поэтому в таких случаях выдайте ошибку или вернитесь раньше.

Вы также не возвращаете обещание, поэтому удалите 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  ); }  

Комментарии:

1. это сработало. Спасибо. еще одна головная боль прошла

Ответ №2:

В этой строке вы говорите, что canvas.width может быть неопределенной:

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

таким образом, вы можете переработать логику, чтобы это было не так. Тем не менее, иногда вы будете знать больше, чем компилятор TypeScript, поэтому, если вы знаете, что значение никогда не будет неопределенным, когда вам нужно получить к нему доступ, вы можете утверждать значение.

 canvas.width as number  

Ответ №3:

Почему вы используете дополнительные поля в интерфейсе обрезки?

Вы пробовали это сделать?:

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

Комментарии:

1. Я этого не делал, я импортировал это из упаковки. я должен был упомянуть, что