我的问题的核心
const FinalComponent<GenericType extends 'a' | 'b'> =
tsx 语法无效。
// The 1st line here is invalid tsx syntax
const FinalComponent<InvalidGenericType extends 'a' | 'b'> =
forwardRef<HTMLParagraphElement, PropsWithStandardRef<InvalidGenericType>>(({ value }, ref) => {
return <Component forwardedRef={ref} value={value} />
}) as ComponentType<InvalidGenericType>
该组件的预期用途:
const ExampleUsage = () => <FinalComponent<'b'> value="b" />
在这种情况下如何创建泛型类型?
额外的背景信息
对于其他上下文,以下是其余代码:
import { Ref, forwardRef } from 'react'
// These are the base props for the component.
// In terms of usage, these are the props that I care about.
interface Props<GenericType extends 'a' | 'b'> {
value: GenericType
}
// Adding forwardedRef to the props to define what props are usable inside the component
interface PropsWithForwardRef<GenericType extends 'a' | 'b'> extends Props<GenericType> {
forwardedRef: Ref<HTMLParagraphElement | null>
}
// Adding standard ref to the props to define what props the component can accept from outside
interface PropsWithStandardRef<GenericType extends 'a' | 'b'> extends Props<GenericType> {
ref?: Ref<HTMLParagraphElement | null>
}
// forwardRef is interfering with the inheritance of the generic types.
// This is a stand in for the expected return type of the component.
type ComponentType<GenericType extends 'a' | 'b'> = (props: PropsWithStandardRef<GenericType>) => JSX.Element
// The core component code
function CoreComponent<GenericType extends 'a' | 'b'> ({ value, forwardedRef }:PropsWithForwardRef<GenericType>):JSX.Element {
return <p ref={forwardedRef}>{value}</p>
}
// !!!!!!!!!!! IMPORTANT BIT !!!!!!!!!!!!
// This is where my problem is, I need to be able to pass a dynamic generic type into PropsWithStandardRef and ComponentType.
// I'm not sure how to do that though because `const FinalComponent<InvalidGenericType extends 'a' | 'b'> = forwardRef()` is invalid
const FinalComponent<InvalidGenericType extends 'a' | 'b'> = forwardRef<HTMLParagraphElement, PropsWithStandardRef<InvalidGenericType>>(({ value }, ref) => {
return <CoreComponent forwardedRef={ref} value={value} />
// I need the `as ComponentType<InvalidGenericType>` bit because the inferred type that comes out of forwardRef
// is making TS lose the generic types information
}) as ComponentType<InvalidGenericType>
// This is the end goal of how I want to be able to use this component
// I want to be able to pass a generic type into the component without TS complaining
const ExampleUsage = () => <FinalComponent<'b'> value="b" />
附言。我认识到这个例子有点做作,它是为了简化我的现实世界问题,该问题具有更复杂的组件。
类似但不同的问题
这不同于React Typescript - 动态类型 https://stackoverflow.com/questions/64208371/react-typescript-dynamic-types
在这个问题中,它不需要将类型信息传递到变量中,而只是根据用户提供的值来更改类型。
我需要组件的最终使用才能将类型传递给它。