Skip to content

Commit

Permalink
Merge pull request #119 from watershed-climate/sterling-06-07-allow_u…
Browse files Browse the repository at this point in the history
…nion_props_on_mapped_components

allow union props on mapped components
  • Loading branch information
iway1 authored Jun 18, 2023
2 parents 21da601 + a0f8a05 commit 436300c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
41 changes: 41 additions & 0 deletions src/__tests__/createSchemaForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,47 @@ describe("createSchemaForm", () => {
expect(screen.queryByTestId(testIds.textFieldTwo)).toBeTruthy();
expect(screen.queryByTestId(testIds.booleanField)).toBeTruthy();
});
it("should allow union props in components", () => {
const testSchema = z.object({
textField: z.string(),
});

function TextField(props: { testText: string } | { testNumber: number }) {
return (
<div>{"testText" in props ? props.testText : props.testNumber}</div>
);
}

const mapping = [[z.string(), TextField] as const] as const;
const TSForm = createTsForm(mapping);

render(
<TSForm
onSubmit={() => {}}
schema={testSchema}
props={{
textField: {
testText: "text",
},
}}
/>
);

expect(screen.queryByText("text")).toBeTruthy();
render(
<TSForm
onSubmit={() => {}}
schema={testSchema}
props={{
textField: {
testNumber: 101,
},
}}
/>
);

expect(screen.queryByText("101")).toBeTruthy();
});
it("should type the onSubmit properly", () => {
const testSchema = z.object({
textField: z.string(),
Expand Down
8 changes: 6 additions & 2 deletions src/createSchemaForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { getComponentForZodType } from "./getComponentForZodType";
import { zodResolver } from "@hookform/resolvers/zod";
import {
DistributiveOmit,
IndexOf,
IndexOfUnwrapZodType,
RequireKeysWithRequiredChildren,
Expand Down Expand Up @@ -210,7 +211,7 @@ export type PropType<
any,
any
] // I guess this tells typescript it has a second element? errors without this check.
? Omit<
? DistributiveOmit<
ComponentProps<GetTupleFromMapping<Mapping, SchemaType, key>[1]>,
PropsMapType[number][1]
> &
Expand Down Expand Up @@ -316,7 +317,10 @@ export type RTFFormProps<
/**
* Props to pass to the form container component (by default the props that "form" tags accept)
*/
formProps?: Omit<ComponentProps<FormType>, "children" | "onSubmit">;
formProps?: DistributiveOmit<
ComponentProps<FormType>,
"children" | "onSubmit"
>;
}>;

/**
Expand Down
7 changes: 5 additions & 2 deletions src/typeUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ export type SafeOmit<T, Key extends keyof T> = IsEmpty<
/**
* @internal
*/
export type DistributiveOmit<T, K extends keyof T> = T extends any
? SafeOmit<T, K>
export type DistributiveOmit<T, K extends keyof T> = T extends T
? // Typescript actually is fine with Omit<T, K>, but this is surprising because
// K might include elements that are not in every member of the union T. In other words,
// K does not extend keyof T.
Omit<T, K & keyof T>
: never;

/**
Expand Down

1 comment on commit 436300c

@vercel
Copy link

@vercel vercel bot commented on 436300c Jun 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.