首页 > 解决方案 > 将联合类型传递给 React 的 useRef 不起作用

问题描述

useRefReact 的类型实现不允许我使用联合类型是否有原因?

我在 TS 方面不是很有经验,因此不能完全理解错误和底层类型的原因。

TS游乐场

function Test() {
    const ref = React.useRef<HTMLInputElement | HTMLButtonElement>(null);

    return Math.random()
        ? <input ref={ref} />
        : <button ref={ref}></button>;        
}

错误:

Type 'RefObject<HTMLInputElement | HTMLButtonElement>' is not assignable to type 'string | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined'.
  Type 'RefObject<HTMLInputElement | HTMLButtonElement>' is not assignable to type 'RefObject<HTMLButtonElement>'.
    Type 'HTMLInputElement | HTMLButtonElement' is not assignable to type 'HTMLButtonElement'.
      Type 'HTMLInputElement' is not assignable to type 'HTMLButtonElement'.
        Types of property 'labels' are incompatible.
          Type 'NodeListOf<HTMLLabelElement> | null' is not assignable to type 'NodeListOf<HTMLLabelElement>'.
            Type 'null' is not assignable to type 'NodeListOf<HTMLLabelElement>'.  TS2322

React 的类型(这样你就不需要查找它们):

interface ClassAttributes<T> extends Attributes {
    ref?: LegacyRef<T>;
}

type Ref<T> = { bivarianceHack(instance: T | null): void }["bivarianceHack"] | RefObject<T> | null;
type LegacyRef<T> = string | Ref<T>;

function useRef<T>(initialValue: T|null): RefObject<T>;

interface RefObject<T> {
    readonly current: T | null;
}

标签: reactjstypescriptreact-hooks

解决方案


试试这样:

import React from 'react';

function Test() {
    const ref = React.useRef<HTMLInputElement | HTMLButtonElement | null>(null);

    return Math.random()
        ? <input ref={(instance) => ref.current = instance} />
        : <button ref={(instance) => ref.current = instance}></button>;        
}

如果您有严格的 null 检查,则需要指定 null (所有类型都没有 undefiened | null 其中)+ ref 有多个签名,因此打字稿无法确定正确的签名。


推荐阅读