as
Prop not working with derived component
#56
-
Dear communit 😊, How do I make the Am I using the wrong pattern? How do I make this work? Example: import { classed } from '@tw-classed/react'
import { forwardRef } from 'react'
const BasicButton = classed('button', 'some-classes')
type Props = React.ComponentProps<typeof BasicButton>
export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
{ children, ...props },
ref
) {
return (
<BasicButton {...props} ref={ref}>
{/*
Do stuff here.
E.g. extend props with icon?: SVGSVGElement prop and render icon if present.
*/}
{children}
</BasicButton>
)
})
const OtherComponent = () => (
// Type '"a"' is not assignable to type '"button"'.ts(2322)
// index.d.ts(14, 5): The expected type comes from property 'as' which is declared here on type 'IntrinsicAttributes & Pick<Omit<Pick<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "key" | keyof ButtonHTMLAttributes<...>> & { ...; }, "as"> & { ...; }, "as" | ... 1 more ... | keyof ButtonHTMLAttributes<...>> & RefAttributes<...>'
// vv
<Button as="a" href="https://test.com">
Test
</Button>
) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Hello! This issue is caused by the React internal typings as somehow manage to flatten the type of BasicButton. Any library using polymorphism seems to have this problem. Its an easy fix though! What you need to do is re-map the button after its created. Like so: Edit 3 - Now fixedReleased a fix in Canary import type { DerivedComponentType } from "@tw-classed/react";
export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
{ children, ...props },
ref
) {
return (
<BasicButton {...props} ref={ref}>
{/*
Do stuff here.
E.g. extend props with icon?: SVGSVGElement prop and render icon if present.
*/}
{children}
</BasicButton>
);
}) as DerivedComponentType<typeof BasicButton, Props>; Previous fix on 1.2.5: export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
{ children, ...props },
ref
) {
return (
<BasicButton {...props} ref={ref}>
{/*
Do stuff here.
E.g. extend props with icon?: SVGSVGElement prop and render icon if present.
*/}
{children}
</BasicButton>
);
}) as ClassedComponentType<typeof BasicButton>; Now the I am definitely looking into this, we might have to export a new type which can be used in place of As for the Edit 2 type Props = React.ComponentProps<typeof BasicButton> & {
// Add additional props here.
icon?: React.ReactNode;
};
export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
{ children, ...props },
ref
) {
return (
<BasicButton {...props} ref={ref}>
{/*
Do stuff here.
E.g. extend props with icon?: SVGSVGElement prop and render icon if present.
*/}
{children}
</BasicButton>
);
}) as ClassedComponentType<typeof BasicButton, Omit<Props, "as">>; // Omit the as prop to avoid confusing TS
() => <Button as="a" href="/" />
() => <Button as="a" href="/" icon={LinkIcon} /> |
Beta Was this translation helpful? Give feedback.
-
I'll attempt to create a special exported type that combines what I just showed into one type :). |
Beta Was this translation helpful? Give feedback.
-
Wow, you're awesome. Thank you for your immediate help and |
Beta Was this translation helpful? Give feedback.
Hello!
This issue is caused by the React internal typings as somehow manage to flatten the type of BasicButton. Any library using polymorphism seems to have this problem.
Its an easy fix though! What you need to do is re-map the button after its created. Like so:
Edit 3 - Now fixed
Released a fix in Canary
npm i @tw-classed/react@canary
See the Creating a derived component docs.