Last active
March 24, 2021 16:24
-
-
Save cchaos/56d0bcfe0c4f4fb47148056bf1627b77 to your computer and use it in GitHub Desktop.
EUI: Restricted props with Typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react'; | |
| import { ExclusiveUnion } from '../common'; | |
| /** | |
| * 1. Use the EUI provided ExclusiveUnion to separate unique props. | |
| */ | |
| type _RestrictedProps = ExclusiveUnion< | |
| { | |
| /** | |
| * 2. At least one of the unique props must be required, usually the one containing more options | |
| */ | |
| position: 'fixed'; | |
| /** | |
| * 3. These next props are only available when `position` is `fixed` | |
| */ | |
| foo?: boolean; | |
| bar?: boolean; | |
| }, | |
| { | |
| /** | |
| * 4. These are the other options that can't be used in conjunction with the above props | |
| */ | |
| position?: 'static' | 'sticky'; | |
| } | |
| >; | |
| export interface EuiComponentProps | |
| extends _RestrictedProps { | |
| /** | |
| * 5. Add all your other props that are allowed no matter the other configurations | |
| */ | |
| stuff?: string; | |
| } | |
| export const EuiComponent: FunctionComponent<EuiComponentProps> = ({ | |
| position = 'fixed', | |
| foo = true, | |
| bar = true, | |
| stuff, | |
| ...rest | |
| }) => { | |
| /** | |
| * 6. Still ensure the props values are correct for the particular configuration | |
| */ | |
| foo = position !== 'fixed' ? false : foo; | |
| bar = position !== 'fixed' ? false : bar; | |
| return (); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react'; | |
| import { ExclusiveUnion } from '@elastic/eui'; | |
| export interface MyComponentProps { | |
| /** | |
| * 7. This component allows consumers to override defaults supplied to the resctricted component | |
| */ | |
| overrides?: EuiComponentProps; | |
| } | |
| export const MyComponent: FunctionComponent<MyComponentProps> = ({ | |
| overrides, | |
| }) => { | |
| return ( | |
| <EuiComponent | |
| position="sticky" | |
| // 8. Typescript will always complain, so using unknown here, | |
| // but it won't restrict consumers from providing incompatible props, so ensure the EUI component handles that (see #6) | |
| {...(overrides as unknown)} | |
| /> | |
| ); | |
| } |
Author
Author
❤️ Thank you all for your help and input. I've updated this gist to exemplify both the "finalized" component and usage that we can link to in our EUI wiki.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Haha, apparently this one is being super tricky. Everything that you just said works and makes sense. Except now when I want to JUST adjust the prop allowed when
position="fixed". So this:But, even though
position="fixed"is the default, TS complains telling me I need to add it.