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

基于Prop的TypeScript条件类型未按预期工作问题

基于Prop的条件类型

我遇到了一个问题:在React组件中,多个类型依赖于单个prop,这些类型不能混用,且由于它们共享同一prop的依赖,本不应出现混用情况。但TypeScript无法根据该prop推断泛型类型。以下是简化为纯JavaScript函数的代码示例:

type AsType = "input" | "select"

type ForwardedRef<T extends HTMLElement> = (instance: T) => void

type RefType<T extends AsType> = T extends "input"
  ? ForwardedRef<HTMLInputElement>
  : T extends "select"
  ? ForwardedRef<HTMLSelectElement>
  : never

type PropsType<T extends AsType>  = {
    className?: string
    as?: T
}

function Select({ forwardedRef }: { forwardedRef: ForwardedRef<HTMLSelectElement> }) {
    console.log("Select", forwardedRef)
}

function Input({ forwardedRef }: { forwardedRef: ForwardedRef<HTMLInputElement> }) {
    console.log("Input", forwardedRef)
}

function test<T extends AsType = "input">(props: PropsType<T>, forwardedRef: RefType<T>) {
    if (props.as === "input") {
        // Typescript error: Type 'ForwardedRef<HTMLInputElement> | ForwardedRef<HTMLSelectElement>' is not assignable to type 'ForwardedRef<HTMLInputElement>'.
        return Input({ forwardedRef }) 
    } else {
        // Typescript error: Type 'ForwardedRef<HTMLInputElement> | ForwardedRef<HTMLSelectElement>' is not assignable to type 'ForwardedRef<HTMLInputElement>'.
        return Select({ forwardedRef }) 
    }
}

代码也可在TypeScript Playground中查看。

如果我写Select({ ref: ref as ForwardedRef<"select"> })可以解决问题,但我非常不想这样做,尤其是在我的实际项目中,除了ref还有更多依赖HTMLElement子类型的props(如onCreate、onBlur等处理器)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:07:00