#Getting typeof React component props when passed as TSX

2 messages · Page 1 of 1 (latest)

lofty vine
#

I'm designing a window component/context system that has an openWindow method and accepts TSX. It works fine but I'm trying to design it so that typescript properly knows the return value. When windows are closed they pass result data to an onClose function so I want openWindow to always return whatever a window's onClose is typed to return.

The problem is that I don't see any way to obtain that information when passing the component as TSX - I'd have to pass a generic myself OR pass the component pointer. Neither of those are ideal from a dev experience perspective so I'm hoping there's some solution.

Below is an extremely simplified example of what I want - a component uses a ClickProp interface and sets a generic to declare it's return function.

// Some shared, global interface
interface ClickProp<T> {
  onClick: () => T
}

type TestComponentProps = ClickProp<string>

// One of many components that use the interface
const Test = ({ onClick }: TestComponentProps): JSX.Element => <button onClick={onClick}>click</button>

// A function that will do stuff with JSX and return the result of a specific prop (in reality, an async function result)
const someFunction = <T extends ClickProp<any>>(element: ReactElement<T>): T => {
  // calls element.props.onClick and returns the result
}

// result should ideally match the return value of the `onClick` prop
const result = someFunction(<Test onClick={() => 'test' } />)

// I can make this work if I design either of these approaches, but they're not as easy on a developer as I'd like:

// const result = someFunction<TestComponentProps>(<Test onClick={() => 'test' } />) // forces a dev to manually declare the props interface
// const result = someFunction=(Test, { onClick: () => 'test' }) // Can use generics but forces dev to pass component/props separately, which isn't typical
twilit ember
#

@lofty vine The result of TSX syntax is just JSX.Element - so there really isn't a way to do use the types of the a passed component or children.