Skip to content
⚠️ This article was written in 2022. Some content may be outdated.

TypeScript Enums vs Union Types

TypeScript enums vs union types is being applied more and more widely in frontend development. This article starts from real projects and digs into the core principles and best practices.

Basic Usage ​

We can improve it in the following ways:

javascript
import { useRef, useEffect, useState } from 'react'

function useIntersectionObserver(options = {}) {
  const [isVisible, setIsVisible] = useState(false)
  const ref = useRef(null)

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setIsVisible(entry.isIntersecting)
    }, { threshold: 0.1, ...options })
    const el = ref.current
    if (el) observer.observe(el)
    return () => { if (el) observer.unobserve(el) }
  }, [])

  return [ref, isVisible]
}

This approach has been running stably in production for over six months and has been practically validated.

Advanced Usage ​

Let's start with the basic implementation:

javascript
.container {
  width: min(90%, 1200px);
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 3rem);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

.card { container-type: inline-size; }

@container (min-width: 400px) {
  .card__content { display: grid; grid-template-columns: 200px 1fr; }
}

This code shows the basic usage. In real projects you also need to think about error handling and edge cases.

Practical Cases ​

Building on this foundation, we can further optimize:

javascript
const fs = require('fs')
const { Transform, pipeline } = require('stream')
const { promisify } = require('util')
const pipelineAsync = promisify(pipeline)

const csvToJson = new Transform({
  transform(chunk, encoding, callback) {
    const lines = chunk.toString().split('\n')
    const headers = lines[0].split(',')
    for (let i = 1; i < lines.length; i++) {
      if (!lines[i].trim()) continue
      const values = lines[i].split(',')
      const obj = {}
      headers.forEach((h, idx) => obj[h.trim()] = values[idx]?.trim())
      this.push(JSON.stringify(obj) + '\n')
    }
    callback()
  }
})

This pattern is very practical in large projects and can significantly reduce maintenance costs.

Performance Optimization ​

Usage in real projects is a bit more complex:

javascript
import { useRef, useEffect, useState } from 'react'

function useIntersectionObserver(options = {}) {
  const [isVisible, setIsVisible] = useState(false)
  const ref = useRef(null)

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setIsVisible(entry.isIntersecting)
    }, { threshold: 0.1, ...options })
    const el = ref.current
    if (el) observer.observe(el)
    return () => { if (el) observer.unobserve(el) }
  }, [])

  return [ref, isVisible]
}

Through this approach, both the testability and scalability of the code are improved.

Common Traps ​

Here is a complete example:

javascript
.container {
  width: min(90%, 1200px);
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 3rem);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

.card { container-type: inline-size; }

@container (min-width: 400px) {
  .card__content { display: grid; grid-template-columns: 200px 1fr; }
}

Pay attention to boundary condition handling, which is critical in production.

Summary ​

  • Stay updated with the community; technical solutions need continuous iteration
  • Don't adopt new technology just for the sake of it
  • Code examples are for reference only and need to be adjusted according to your business scenario
  • TypeScript enums vs union types is not a silver bullet — choose based on your project scale and tech stack
  • Understanding underlying principles is more important than memorizing APIs

MIT Licensed