Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpocock committed Jul 24, 2023
1 parent ac5e74f commit 704e257
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Equal, Expect } from "../helpers/type-utils";

import { ForwardedRef, forwardRef } from "react";

type FixedForwardRef = <T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
) => (props: P & React.RefAttributes<T>) => React.ReactNode;

const fixedForwardRef = forwardRef as FixedForwardRef;

type Props<T> = {
data: T[];
renderRow: (item: T) => React.ReactNode;
};

export const Table = <T,>(props: Props<T>, ref: ForwardedRef<any>) => {
return null;
};

const ForwardReffedTable = fixedForwardRef(Table);

const Parent = () => {
return (
<ForwardReffedTable
data={["123"]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, string>>;
return <div>123</div>;
}}
></ForwardReffedTable>
);
};
37 changes: 37 additions & 0 deletions src/08-advanced-patterns/72.5-as-prop-with-forward-ref.problem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ComponentPropsWithoutRef, ElementType, forwardRef } from "react";
import { Equal, Expect } from "../helpers/type-utils";

export const Link = forwardRef(
<T extends ElementType<any> = "a">(
props: {
as?: T;
} & ComponentPropsWithoutRef<T>,
) => {
const { as: Comp = "a", ...rest } = props;
return <Comp {...rest}></Comp>;
},
);

<Link href="/"></Link>;

const Custom = (props: { thisIsRequired: boolean }) => {
return null;
};

<Link as={Custom} thisIsRequired />;

// @ts-expect-error Property 'thisIsRequired' is missing
<Link as={Custom} />;

<Link
as="button"
onClick={(e) => {
type test = Expect<Equal<typeof e, React.MouseEvent<HTMLButtonElement>>>;
}}
></Link>;

<Link
as="div"
// @ts-expect-error: Property 'href' does not exist
href="awdawd"
></Link>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
ComponentProps,
ComponentPropsWithoutRef,
ElementType,
forwardRef,
useRef,
} from "react";
import { Equal, Expect } from "../helpers/type-utils";

type FixedForwardRef = <T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
) => (props: P & React.RefAttributes<T>) => React.ReactNode;

const fixedForwardRef = forwardRef as FixedForwardRef;

export const Link = fixedForwardRef(
<T extends ElementType = "a">(
props: {
as?: T;
} & ComponentProps<T>,
) => {
const { as = "a", ...rest } = props;
const Comp = as as any;
return <Comp {...rest}></Comp>;
},
);

const Test = () => {
const ref = useRef<HTMLAnchorElement>(null);

return <Link as="a" href="/" ref={ref}></Link>;
};

const Custom = (props: { thisIsRequired: boolean }) => {
return null;
};

<Link as={Custom} thisIsRequired />;

// @ts-expect-error Property 'thisIsRequired' is missing
<Link as={Custom} />;

const ref = useRef<HTMLButtonElement>(null);

<Link
as="button"
onClick={(e) => {
type test = Expect<Equal<typeof e, React.MouseEvent<HTMLButtonElement>>>;
}}
ref={ref}
></Link>;

<Link
as="div"
// @ts-expect-error: Property 'href' does not exist
href="awdawd"
></Link>;

0 comments on commit 704e257

Please sign in to comment.