mui / mui/base-ui

Optional stronger type safety with `useRender`

Open
#3,879 0 comments 2 reactions 0 assignees View on GitHub
hook: useRender type: enhancement
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

# Feature request

## Summary

When using `useRender` to create a custom component, I'd like the option to strongly type its `render` prop's `props`.

## Motivation

If a component has any required props:

```tsx
interface InputProps {
name: string;
}

export function Input(props: InputProps): JSX.Element {
return ;
}
```

Then a `render` slot can never accept that component without a type error:

```tsx
type FieldProps = useRender.ComponentProps<"input">;

export function Field({ render, ...props }: FieldProps): JSX.Element {
const defaultProps: useRender.ElementProps<"input"> = {
name: "name",
};

const element = useRender({
defaultTagName: "input",
render,
props: mergeProps<"input">(defaultProps, props),
});

return element;
}

;
// ^^^^^^^
// Property 'name' is missing in type 'HTMLProps' but required in type 'InputProps'.
```

I'm currently working around this with custom types and one `@ts-expect-error`:

```tsx
interface FieldProps extends ComponentPropsWithRef<"input"> {
render?: ReactElement | ComponentType | undefined;
}

interface RenderProps extends ComponentPropsWithRef<"input"> {
name: string;
}

export function Field({ render, ...props }: FieldProps): JSX.Element {
const defaultProps: RenderProps = {
name: "name",
};

const element = useRender({
defaultTagName: "input",
// @ts-expect-error -- Base UI doesn't support typed render props
render,
props: mergeProps<"input">(defaultProps, props),
});

return element;
}

;
```

But I think an "ergonomic" solution would be great, as it could be a powerful pattern for checking compatibility between components.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.