Skip to content

Instantly share code, notes, and snippets.

@marekdano
Last active April 10, 2021 19:15
Show Gist options
  • Save marekdano/32a308a60fc80d6d53478625e75c84ad to your computer and use it in GitHub Desktop.
Save marekdano/32a308a60fc80d6d53478625e75c84ad to your computer and use it in GitHub Desktop.
React TypeScript conditional props - props that depend on other props
// all credits for this gist goes to Bruno's video
// https://www.youtube.com/watch?v=vXh4PFwZFGI
type DrawerProps = { fullName: string } & (
| { shape: 'circle'; radius: number }
| { shape: 'square'; width: number }
| { shape: 'rectangle'; width: number; height: number }
);
<Drawer fullName="Marek Dano" shape="rectangle" width={5} height={4} />
<Drawer fullName="Marek Dano" shape="square" width={4} />
<Drawer fullName="Marek Dano" shape="circle" radius={3} />
type OneOrTheOther =
| { collapsed?: boolean; expanded?: never }
// | { collapsed?: true; expanded?: never } used when false is no accepted
| { collapsed?: never; expanded?: boolean }
<OneOrTheOther />
<OneOrTheOther collapsed />
<OneOrTheOther expanded />
type PanelProps =
| { collapsable: true; defaultCollapsed?: boolean }
// | { collapsable: true; defaultCollapsed?: true }
| { collapsable?: never; defaultCollapsed?: never }
<Panel collapsable defaultCollapsed={false} />
<Panel />
type DropdownProps<T> = T extends number | string ? {
data: Array<string | number>;
labelProp?: never;
valueProp?: never;
} : {
data: Array<T>;
labelProp: keyof T;
valueProp: keyof T;
}
function Dropdown<T>(props: DropdownProps<T>) {
return <div>{JSON.stringify(props)}</div>
}
<Dropdown data={["a", "b"]} />
<Dropdown data={[1, 2]} />
<Dropdown
data={[{id: 1, name: 'marek'}, {id: 2, name: 'tom'}]}
labelProp="name"
valueProp="id"
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment