TypeScript中'ctx可能为null'与'image类型unknown'错误求解
解决TypeScript中的两个错误:'ctx' is possibly 'null' 和 'image' is of type 'unknown'
1. 解决'image' is of type 'unknown'
createImage函数返回值默认是unknown类型,同时你用any作为函数参数类型,丢失了TypeScript的类型检查能力。可以按以下步骤修正:
- 给
createImage定义返回类型为Promise<HTMLImageElement>,如果是你自己实现的函数,直接修改类型;如果是第三方函数,用类型断言明确image的类型。 - 给
imageSrc、pixelCrop替换掉any,使用具体的类型定义。
示例修改:
// 定义pixelCrop的类型 interface PixelCrop { x: number; y: number; width: number; height: number; } // 给自定义的createImage添加类型 async function createImage(src: string): Promise<HTMLImageElement> { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }); } export default async function getCroppedImg( imageSrc: string, pixelCrop: PixelCrop, rotation = 0 ) { // 若无法修改createImage类型,用类型断言 const image = await createImage(imageSrc) as HTMLImageElement; // ... 后续代码 }
2. 解决'ctx' is possibly 'null'
canvas.getContext("2d")在不支持Canvas的环境下会返回null,TypeScript会提示这个风险。有两种处理方式:
安全检查(推荐)
先判断ctx是否存在,再执行后续操作,避免运行时错误:
export default async function getCroppedImg( imageSrc: string, pixelCrop: PixelCrop, rotation = 0 ) { const image = await createImage(imageSrc); const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); // 检查ctx是否存在,不存在则抛出错误或提前返回 if (!ctx) { throw new Error("无法获取Canvas 2D上下文"); } // 后续使用ctx的代码不会再报错 const maxSize = Math.max(image.width, image.height); const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)); canvas.width = safeArea; canvas.height = safeArea; ctx.translate(safeArea / 2, safeArea / 2); ctx.rotate(getRadianAngle(rotation)); ctx.translate(-safeArea / 2, -safeArea / 2); // ... 剩余代码 }
非空断言(仅确定环境支持Canvas时使用)
用!断言ctx不为null,跳过类型检查:
const ctx = canvas.getContext("2d")!;
完整修改后的代码
interface PixelCrop { x: number; y: number; width: number; height: number; } async function createImage(src: string): Promise<HTMLImageElement> { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }); } function getRadianAngle(degreeValue: number): number { return (degreeValue * Math.PI) / 180; } export default async function getCroppedImg( imageSrc: string, pixelCrop: PixelCrop, rotation = 0 ) { const image = await createImage(imageSrc); const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); if (!ctx) { throw new Error("无法获取Canvas 2D上下文"); } const maxSize = Math.max(image.width, image.height); const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)); canvas.width = safeArea; canvas.height = safeArea; ctx.translate(safeArea / 2, safeArea / 2); ctx.rotate(getRadianAngle(rotation)); ctx.translate(-safeArea / 2, -safeArea / 2); ctx.fillStyle = "#DCDCDC"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.drawImage( image, safeArea / 2 - image.width * 0.5, safeArea / 2 - image.height * 0.5 ); const data = ctx.getImageData(0, 0, safeArea, safeArea); canvas.width = pixelCrop.width; canvas.height = pixelCrop.height; ctx.putImageData( data, Math.round(0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x), Math.round(0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y) ); }
内容的提问来源于stack exchange,提问作者Esther
相关产品推荐
相关产品推荐

