How do I avoid

Front-end tech leader

THE NEXT DEVELOPER READING MY CODE

swearing at me

Stefano Magni

Why am I here?

Weeks instead of days

Ambiguity

TypeScript’ Discriminated Unions

Straightforward React components

Explicit State Machines

Cypress integration tests

1. TypeScript’ Discriminated Unions

type Order = {
  name: string
  description?: string
  at: Location
} & ({
  status: 'ready'
} | {
  status: 'inProgress'
  expectedDelivery: Date
} | {
  status: 'complete'
  expectedDelivery: Date
  deliveredOn: Date
})
type Order = {
  status: string
  name: string
  description?: string
  at?: Location
  expectedDelivery?: Date
  deliveredOn?: Date
}
type Order = {
  name: string
  description?: string
  at: Location
} & ({
  status: 'ready'
} | {
  status: 'inProgress'
  expectedDelivery: Date
} | {
  status: 'complete'
  expectedDelivery: Date
  deliveredOn: Date
})
type Order = {
  status: string
  name: string
  description?: string
  at?: Location
  expectedDelivery?: Date
  deliveredOn?: Date
}
type Order = {
  name: string
  description?: string
  at: Location
} & ({
  status: 'ready'
} | {
  status: 'inProgress'
  expectedDelivery: Date
} | {
  status: 'complete'
  expectedDelivery: Date
  deliveredOn: Date
})
type Order = {
  status: string
  name: string
  description?: string
  at?: Location
  expectedDelivery?: Date
  deliveredOn?: Date
}
function createEmailMessage(order: Order) {
 if (order.expectedDelivery) {
  return `${order.name} will be delivered at ${order.expectedDelivery}`
 }

 if (order.deliveredOn) {
  return `${order.name} has been delivered on ${order.deliveredOn}`
 }

 if (!order.expectedDelivery && !order.deliveredOn) {
  return `${order.name} is at ${order.at}`
 }
}
type Order = {
  name: string
  description?: string
  at: Location
} & ({
  status: 'ready'
} | {
  status: 'inProgress'
  expectedDelivery: Date
} | {
  status: 'complete'
  expectedDelivery: Date
  deliveredOn: Date
})
type Order = {
  status: string
  name: string
  description?: string
  at?: Location
  expectedDelivery?: Date
  deliveredOn?: Date
}
function createEmailMessage(order: Order) {
  switch(order.status) {
    case 'ready':
      return `${order.name} is at ${order.at}`

    case 'inProgress':
      return `${order.name} will be delivered at ${order.expectedDelivery}`

    case 'complete':
      return `${order.name} has been delivered at ${order.deliveredOn}`
  }
}
function createEmailMessage(order: Order) {
 //      ^? createEmailMessage(order: Order): string | undefined

 if (order.expectedDelivery) {
  return `${order.name} will be delivered ${order.expectedDelivery}`
 }

 if (order.deliveredOn) {
  return `${order.name} has been delivered on ${order.deliveredOn}`
 }

 if (!order.expectedDelivery && !order.deliveredOn) {
  return `${order.name} is at ${order.at}`
 }
}
function createEmailMessage(order: Order) {
  //     ^? createEmailMessage(order: Order): string
  
  switch(order.status) {
    case 'ready':
      return `${order.name} is at ${order.at}`

    case 'inProgress':
      return `${order.name} will be delivered ${order.expectedDelivery}`

    case 'complete':
      return `${order.name} has been delivered at ${order.deliveredOn}`
  }
}
function createEmailMessage(order: Order) {
 //      ^? createEmailMessage(order: Order): string | undefined

 if (order.expectedDelivery) {
  return `${order.name} will be delivered ${order.expectedDelivery}`
 }

 if (order.deliveredOn) {
  return `${order.name} has been delivered on ${order.deliveredOn}`
 }

 if (!order.expectedDelivery && !order.deliveredOn) {
  return `${order.name} is at ${order.at}`
 }
}
function createEmailMessage(order: Order)  { /* ... */ }
  //     ^? createEmailMessage(order: Order): string
  
const message = createEmailMessage(order)
sendEmail(message)
function createEmailMessage(order: Order) { /* ... */ }
 //      ^? createEmailMessage(order: Order): string | undefined

const message = createEmailMessage(order)
if(message) {
  sendEmail(message)
}

2. Straightforward React components

export function RenderOrder() {
 const [order, setOrder] = useState<Order | undefined>()

 useEffect(() => {
  fetch('https://api.yourdomain.com/latest-order')
   .then(response => response.json())
   .then(order => setOrder(order))
 }, [])

 const onSendEmailClick = useCallback(() => {
  if (!order) return

  const message = createEmailMessage(order)
  if (message) {
   sendEmail(message)
  }
 }, [order])

 if (!order) return null

 return (
  <div>
   <p>
    {order.name} ({order.status})
   </p>
   {order.description && <p>{order.description}</p>}

   {!order.deliveredOn && order.expectedDelivery && (
    <p>Expected delivery: {order.expectedDelivery}</p>
   )}
   {order.deliveredOn && <p>Delivered on: {order.deliveredOn}</p>}

   <button onClick={onSendEmailClick}>Send email</button>
  </div>
 )
} 
export function RenderOrder() {
 const [order, setOrder] = useState<Order | undefined>()

 useEffect(() => {
  fetch('https://api.yourdomain.com/latest-order')
   .then(response => response.json())
   .then(order => setOrder(order))
 }, [])

 const onSendEmailClick = useCallback(() => {
  if (!order) return

  const message = createEmailMessage(order)
  if (message) {
   sendEmail(message)
  }
 }, [order])

 if (!order) return null

 return (
  <div>
   <p>
    {order.name} ({order.status})
   </p>
   {order.description && <p>{order.description}</p>}

   {!order.deliveredOn && order.expectedDelivery && (
    <p>Expected delivery: {order.expectedDelivery}</p>
   )}
   {order.deliveredOn && <p>Delivered on: {order.deliveredOn}</p>}

   <button onClick={onSendEmailClick}>Send email</button>
  </div>
 )
} 
export function RenderOrder() {
  const fetchStatus = useFetchOrder()
 
  if (fetchStatus.status === 'loading')
    return <p>Loading...</p>
 
  const order = fetchStatus.order
 
  switch (order.status) {
   case 'ready':
    return <ReadyOrder order={order} />
 
   case 'inProgress':
    return <InProgressOrder order={order} />
 
   case 'complete':
    return <CompleteOrder order={order} />
  }
 }
export function RenderOrder() {
  const fetchStatus = useFetchOrder()
 
  if (fetchStatus.status === 'loading')
    return <p>Loading...</p>
 
  const order = fetchStatus.order
 
  switch (order.status) {
   case 'ready':
    return <ReadyOrder order={order} />
 
   case 'inProgress':
    return <InProgressOrder order={order} />
 
   case 'complete':
    return <CompleteOrder order={order} />
  }
 }
type Props = {
 order: Order
}

export function CompleteOrder(props: Props) {
 const { order } = props

 if (order.status !== 'complete') return null

 const { name, description, deliveredOn } = order

 return (
  <div>
   <OrderHeading name={name} description={description} />

   <p>Delivered on: {deliveredOn}</p>

   <SendEmailButton order={order} />
  </div>
 )
}
export function RenderOrder() {
  const fetchStatus = useFetchOrder()
 
  if (fetchStatus.status === 'loading')
    return <p>Loading...</p>
 
  const order = fetchStatus.order
 
  switch (order.status) {
   case 'ready':
    return <ReadyOrder order={order} />
 
   case 'inProgress':
    return <InProgressOrder order={order} />
 
   case 'complete':
    return <CompleteOrder order={order} />
  }
 }
type Props = {
 order: Order
}

export function CompleteOrder(props: Props) {
 const { order } = props

 if (order.status !== 'complete') return null

 const { name, description, deliveredOn } = order

 return (
  <div>
   <OrderHeading name={name} description={description} />

   <p>Delivered on: {deliveredOn}</p>

   <SendEmailButton order={order} />
  </div>
 )
}
export function RenderOrder() {
  const fetchStatus = useFetchOrder()
 
  if (fetchStatus.status === 'loading')
    return <p>Loading...</p>
 
  const order = fetchStatus.order
 
  switch (order.status) {
   case 'ready':
    return <ReadyOrder order={order} />
 
   case 'inProgress':
    return <InProgressOrder order={order} />
 
   case 'complete':
    return <CompleteOrder order={order} />
  }
 }
type CompletedOrder =
  Extract<Order, { status: 'complete' }>

type Props = {
 order: CompletedOrder
}

export function CompleteOrder(props: Props) {
 const { order } = props
 const { name, description, deliveredOn } = order

 return (
  <div>
   <OrderHeading name={name} description={description} />

   <p>Delivered on: {deliveredOn}</p>

   <SendEmailButton order={order} />
  </div>
 )
}
export function RenderOrder() {
  const fetchStatus = useFetchOrder()
 
  if (fetchStatus.status === 'loading')
    return <p>Loading...</p>
 
  const order = fetchStatus.order
 
  switch (order.status) {
   case 'ready':
    return <ReadyOrder order={order} />
 
   case 'inProgress':
    return <InProgressOrder order={order} />
 
   case 'complete':
    return <CompleteOrder order={order} />
  }
 }
type CompletedOrder =
  Extract<Order, { status: 'complete' }>

type Props = {
 order: CompletedOrder
}

export function CompleteOrder(props: Props) {
 const { order } = props
 const { name, description, deliveredOn } = order

 return (
  <div>
   <OrderHeading name={name} description={description} />

   <p>Delivered on: {deliveredOn}</p>

   <SendEmailButton order={order} />
  </div>
 )
}

3. Explicit State Machines

Everything is a State Machine

Hard-to-follow

data flows

The intersection among the previous points

Navigation

Shopify connection status

Admin privileges

The intersection among the previous points

type AppStatus =
  | { status: 'showConnect' }
  | { status: 'showNonAdminError' }
  | { status: 'showSelectOrdersInstructions' }
  | // etc.

Navigation

Shopify connection status

Admin privileges

The intersection among the previous points

type AppStatus =
  | { status: 'showConnect' }
  | { status: 'showNonAdminError' }
  | { status: 'showSelectOrdersInstructions' }
  | // etc.
useEffect(() => {
  switch (currentPage) {
    case 'connect':

Navigation

Shopify connection status

Admin privileges

The intersection among the previous points

type AppStatus =
  | { status: 'showConnect' }
  | { status: 'showNonAdminError' }
  | { status: 'showSelectOrdersInstructions' }
  | // etc.
useEffect(() => {
  switch (currentPage) {
    case 'connect':
      switch (howUserNavigated('connect')) {
        // ------------------------------------------------------------------
        // SCENARIO: the server redirected the user to the connect page
        // ------------------------------------------------------------------
        case 'sentFromServer':













        // ------------------------------------------------------------------
        // SCENARIO: the user navigated directly to the connect page
        // ------------------------------------------------------------------
        case 'directNavigation':

Navigation

Shopify connection status

Admin privileges

The intersection among the previous points

type AppStatus =
  | { status: 'showConnect' }
  | { status: 'showNonAdminError' }
  | { status: 'showSelectOrdersInstructions' }
  | // etc.
useEffect(() => {
  switch (currentPage) {
    case 'connect':
      switch (howUserNavigated('connect')) {
        // ------------------------------------------------------------------
        // SCENARIO: the server redirected the user to the connect page
        // ------------------------------------------------------------------
        case 'sentFromServer':
          switch (connectStatus.status) {
            case 'notRequestedYet':
            case 'failed':




            case 'succeeded':


          }
          break

        // ------------------------------------------------------------------
        // SCENARIO: the user navigated directly to the connect page
        // ------------------------------------------------------------------
        case 'directNavigation':

Navigation

Shopify connection status

Admin privileges

The intersection among the previous points

type AppStatus =
  | { status: 'showConnect' }
  | { status: 'showNonAdminError' }
  | { status: 'showSelectOrdersInstructions' }
  | // etc.
useEffect(() => {
  switch (currentPage) {
    case 'connect':
      switch (howUserNavigated('connect')) {
        // ------------------------------------------------------------------
        // SCENARIO: the server redirected the user to the connect page
        // ------------------------------------------------------------------
        case 'sentFromServer':
          switch (connectStatus.status) {
            case 'notRequestedYet':
            case 'failed':
              // when the connect succeeds, this effect is re-triggered
              setStatus({ status: 'showConnect' })
              break

            case 'succeeded':
              setStatus({ status: 'showSelectOrdersInstructions' })
              break
          }
          break

        // ------------------------------------------------------------------
        // SCENARIO: the user navigated directly to the connect page
        // ------------------------------------------------------------------
        case 'directNavigation':
          redirectTo('home') // as a result, this effect is re-triggered
          break
      }
      break

Navigation

Shopify connection status

Admin privileges

4. Cypress Integration tests

What the app does from a User perspective?

The devs that read my code...

Tests - What data the app exchanges with the server

React components - App's structure

Tests - What the app does

State Machine - How the app works

Types - Domain-related knowledge

They will blame me...

Days instead of weeks

Thank you! ❤️

Front-end tech leader

Stefano Magni

[BACKUP] How do I avoid the next developer reading my code swearing at me (ReactJSDay 2022 talk)

By Stefano Magni

[BACKUP] How do I avoid the next developer reading my code swearing at me (ReactJSDay 2022 talk)

Reading, understanding, and refactoring a TypeScript+React application can be challenging, even if it's small. I will tell you my story of when I jumped on the codebase of a small product to implement some last-minute changes before going live. I had an overall idea of what the product does, and the external team that worked on it received comprehensive documentation of our coding patterns and thorough code reviews. Despite that, being effective since the first day was hard for me. Why? Because four of the most important details that make a codebase immediately readable were missing, which are: - TypeScript' Discriminated Unions instead of optional properties (helpful to describe the domain) - Straightforward JSX code (ease reading and jumping through the code) - Explicit State Machines (describe what the app does from an internal perspective) - Cypress integration tests (tell what the app does from an external perspective) Apart from a long series of best practices, the listed ones are the most used in WorkWave RouteManager, a 250k-LOC front-end application.

  • 2,197