我有以下代码;
App.tsx
export default function App() {
const [canvasRef, canvasWidth, canvasHeight] = useCanvas();
return (
<div>
<canvas
ref={canvasRef}
/>
</div>
)
}
useCanvas.ts
import { useRef, useEffect } from "react";
const canvasWidth = 1200;
const canvasHeight = 600;
export default function useCanvas() {
const canvasRef = useRef<HTMLCanvasElement>(null);
return [canvasRef, canvasWidth, canvasHeight]
}
是的,这正是我在代码中所拥有的,但是,我从Vscode收到App.tsx中的以下错误;
(JSX attribute) React.ClassAttributes<HTMLCanvasElement>.ref?: string | React.RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined
Type 'number | RefObject<HTMLCanvasElement>' is not assignable to type 'string | RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined'.
Type 'number' is not assignable to type 'string | RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined'.ts(2322)
index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement>'
任何建议将不胜感激。
答案 0 :(得分:0)
function useCanvas() {
const canvasRef = useRef<HTMLCanvasElement>(null);
return [canvasRef, canvasWidth, canvasHeight]
}
由于您没有给返回值指定类型,因此typescript会推断出它。在推断数组的类型时,打字稿将假定它是普通数组,而不是tuple。
为简化起见,假设您要返回此代码:
function () {
return [1, 'a'];
}
Typescript将推断类型为(number | string)[]
。换句话说,是任意长度的数组,其中每个元素可以是字符串的数量。它不会不推断类型为[number, string]
。因此,如果您尝试与该数组的索引0进行交互,则打字稿将无法告诉您这绝对是一个数字,只能告诉您它是一个数字或字符串。
因此,您的第一个选择是为要返回的内容提供显式类型。在我的简化情况下,它将是:
function () {
const result: [number, string] = [1, 'a'];
return result;
}
// or
function (): [number, string] {
return [1, 'a'];
}
// or
function () {
return [1, 'a'] as [number, string];
}
我不确定代码类型是否正确,但是您可以检查变量并找出答案。
另一种选择,也许是更简单的选择,是使用as const
来帮助打字稿推断类型。 as const
告诉我们这将永远不会改变,因此它将把它视为一个元组而不是一个数组。
function useCanvas() {
const canvasRef = useRef<HTMLCanvasElement>(null);
return [canvasRef, canvasWidth, canvasHeight] as const;
}
答案 1 :(得分:0)
自定义钩子的返回类型为(number | React.MutableRefObject<HTMLCanvasElement>)[]
,因为typescript推断它返回了包含这些类型的数组。这就是为什么您无法正确键入App.tsx
中解构的变量的原因(如果将其悬停,它们将全部属于number | React.MutableRefObject<HTMLCanvasElement>
类型。)
您需要使用一个元组来准确告诉打字稿此数组中包含的内容。
您可以像这样将键入信息添加到自定义钩子中:
import { useRef, useEffect, MutableRefObject } from "react";
const canvasWidth = 1200;
const canvasHeight = 600;
export default function useCanvas(): [MutableRefObject<HTMLCanvasElement>, number, number] {
const canvasRef = useRef<HTMLCanvasElement>(null);
return [canvasRef, canvasWidth, canvasHeight]
}