about icon indicating copy to clipboard operation
about copied to clipboard

Clean up interfaces

Open zlonko opened this issue 2 years ago • 6 comments

Standardize our interfaces with the same naming convention and file structure. Please see this comment for reference.

zlonko avatar May 24 '22 18:05 zlonko

Here's what I'm thinking to clean up and standardize our interfaces with file organization and naming conventions:

Rules of thumb/style guide:

  1. If one or more interfaces are needed for a specific component or page, scope and keep them within the component or page
  2. If one or more interfaces are needed for many components or pages within the same directory, collocate a file and export the interfaces to import them in the necessary components or pages
  3. If one or more interfaces are needed in many pages or components across the codebase, add them to our common/shared interfaces directory and export them

Example of a scoped interface inside a component

In this case, keep scoped interfaces within the component. Note how it's possible to keep the same namespace since they are thrown away at runtime. Open to standardizing the naming convention to always be {Name}Props for convenient search and batch changes.

components/Button.tsx

import { FunctionComponent } from 'react'

interface Button {
    text: string
}

export const Button: FunctionComponent<Button> = ({ text }) => (
    <button type="button">
        {text}
    </button>
)

Example of an interface inside a component that's been imported

In this case, if the interface is used within the same directory for many sibling/colocated components/pages, add them to a collocated file.

components/Button/buttonProps.ts

export interface ButtonProps {
    text: string
}

components/Button/index.tsx

import { FunctionComponent } from 'react'

import { ButtonProps } from './buttonProps'

export const Button: FunctionComponent<ButtonProps> = ({ text }) => (
    <button type="button">
        {text}
    </button>
)

Example of an interface inside a component that's been imported from our common/shared interfaces directory

In this case, if the interface is used within many components/pages across the codebase, add them to our common/shared interfaces directory to be imported in the necessary components/pages.

interfaces/index.ts

export * from './buttonProps'

interfaces/buttonProps.ts

export interface ButtonProps {
    text: string
}

component/Button.tsx

import { FunctionComponent } from 'react'

import { ButtonProps } from '@interfaces'

export const Button: FunctionComponent<ButtonProps> = ({ text }) => (
    <button type="button">
        {text}
    </button>
)

bretthayes avatar Jun 08 '22 22:06 bretthayes

Thank you, Brett. This provides a lot of clarity as we scale the About site. My only thought at this time is that I prefer the maintenance advantages of a single naming convention. To me this seems more straightforward in the long-term, especially if we want to change this convention down the road. I am open to what others think as well!

zlonko avatar Jun 09 '22 19:06 zlonko

I like this! I think it makes sense. Collocate as much as possible, up-leveling the interface only where necessary. Once it's implemented, we can document the structure in our README for history, for any new developers stepping in the project, etc.

image

st0nebreaker avatar Jun 09 '22 22:06 st0nebreaker

@bretthayes & @st0nebraker Checking for clarity: Shall we stick with two naming conventions or one?

zlonko avatar Jun 16 '22 23:06 zlonko

@zlonko I'm leaning more towards one for much more robust search and batch changes. {YourInterfaceName}Props

bretthayes avatar Jun 16 '22 23:06 bretthayes

@st0nebraker just following up to define how we can tackle this progressively going forward by creating new logic and updating logic as we come across it. Let's use the following style guide to help us:

  • Keep all interfaces scoped at the top of our files defined directly under imports
  • Use the same interface name as the component name and don't export it unless it's used in other files
  • In the rare case that there is a namespace conflict with an exported interface being used as a type, we can use the Props suffix for the naming convention. (ie: ButtonProps)
  • Use simplistic descriptive names for components which will help define interface names

With the future blog work that will be done, this will potentially allow us to remove the common/global interfaces directory as I don't think we'll have a need for global interfaces. But if something comes up, we can just continue the conversation here in this issue to help improve and shape our style guide even more.

Some useful references that helped shape this style guide:

bretthayes avatar Jul 25 '22 16:07 bretthayes