You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何drawImage无法接收参数?napi-rs/canvas类型错误排查

问题:调用drawImage时触发TypeScript类型不兼容错误

问题场景

执行这段代码时出现TypeScript错误:

context.drawImage(img, img.width, img.height)

错误提示

This expression is not callable.
Each member of the union type '{ (image: CanvasImageSource, dx: number, dy: number): void; (image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void; (image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void; } | { ...; }' has signatures, but none of those signatures are compatible with each other.ts(2349)

对应的drawImage类型定义:

(property) drawImage: {
    (image: Image | Canvas, dx: number, dy: number): void;
    (image: Image | Canvas, dx: number, dy: number, dw: number, dh: number): void;
    (image: Image | Canvas, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
} | {
    ...;
}

相关代码

当前函数的参数签名:

const drawFrame = (
    context: CanvasRenderingContext2D | SKRSContext2D,
    positions: typeof startPositions,
    title: string,
    text: string,
    img: Image,
    locale?: string
) => {

使用@napi-rs/canvas库的导入语句:

import {
    createCanvas,
    GlobalFonts,
    Image,
    loadImage,
    SKRSContext2D,
} from '@napi-rs/canvas'

错误原因

核心问题是context是浏览器原生CanvasRenderingContext2D和**@napi-rs/canvas的SKRSContext2D**的联合类型,两者的drawImage方法签名不兼容:

  • 原生CanvasRenderingContext2D.drawImage的第一个参数接受CanvasImageSource(包含Image、Canvas、Video等多种类型)
  • SKRSContext2D.drawImage的第一个参数只限定为Image | Canvas
  • TypeScript对联合类型的方法调用会严格校验所有分支的签名兼容性,哪怕你传入的img是符合要求的Image类型,也无法通过联合类型的签名校验

解决办法

1. 类型收窄

在调用drawImage前,把context断言为具体类型:

// 直接断言为其中一种类型
(context as SKRSContext2D).drawImage(img, img.width, img.height);

// 或者做类型判断后断言
if ('fillText' in context) { // 用特征方法区分两种上下文
    (context as CanvasRenderingContext2D).drawImage(img, img.width, img.height);
} else {
    (context as SKRSContext2D).drawImage(img, img.width, img.height);
}

2. 统一参数类型

如果你的代码只在Node环境用@napi-rs/canvas,直接把context的类型改成SKRSContext2D就行:

const drawFrame = (
    context: SKRSContext2D, // 移除CanvasRenderingContext2D
    positions: typeof startPositions,
    title: string,
    text: string,
    img: Image,
    locale?: string
) => {
    context.drawImage(img, img.width, img.height); // 直接调用无报错
}

3. 写兼容包装函数

封装一个适配两种上下文的函数,跳过类型校验:

function drawImage(
    ctx: CanvasRenderingContext2D | SKRSContext2D,
    img: Image,
    ...args: number[]
) {
    (ctx as any).drawImage(img, ...args);
}

// 使用时直接调用
drawImage(context, img, img.width, img.height);

内容的提问来源于stack exchange,提问作者Alma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:55:14