From ca992c66576cf9a5873c4413da351f26933bfe05 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Sun, 6 Mar 2022 20:00:36 -0500 Subject: [PATCH] Revised Component types (children, readonly, ref) * Rename past `Component` type to `ComponentWithChildren`. Motivation: Most components don't actually support children. This causes a type error upon accidental passing of children / forces you to think about which components support children. * Added second parameter to `ComponentWithChildren` to make it easier to give a custom type for `children` (but still defaults to useful `JSX.Element`). * New `Component` type does not have automatic `children` property (like React's preferred `VoidFunctionalComponent`), offering another natural way to type `props.children`: `Component<{children: JSX.Element}>`. * `props` argument in both `Component` and `ComponentWithChildren` automatically cast to `readonly` (shallow one level only), to avoid accidental assignment to `props.foo` (usually a getter) while still allowing passing mutables in props. Add `Props` helper for this transformation. * Add @LXSMNSYC's `Ref` type so it's easy to type `props.ref`: `Component<{ref: Ref}>`. Fixes #778. --- packages/solid/src/render/component.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/solid/src/render/component.ts b/packages/solid/src/render/component.ts index 43b7c5400..8647611ec 100644 --- a/packages/solid/src/render/component.ts +++ b/packages/solid/src/render/component.ts @@ -15,8 +15,12 @@ export function enableHydration() { hydrationEnabled = true; } -export type PropsWithChildren

= P & { children?: JSX.Element }; -export type Component

= (props: PropsWithChildren

) => JSX.Element; +export type Props

= Readonly

; +export type PropsWithChildren

= + Props

& { readonly children?: C }; +export type Component

= (props: Props

) => JSX.Element; +export type ComponentWithChildren

= + (props: PropsWithChildren) => JSX.Element; /** * Takes the props of the passed component and returns its type * @@ -30,6 +34,12 @@ export type ComponentProps}> + */ +export type Ref = T | ((val: T) => void); + export function createComponent(Comp: (props: T) => JSX.Element, props: T): JSX.Element { if (hydrationEnabled) { if (sharedConfig.context) {