이 글은 <React Prop Types with TypeScript>를 번역한 글입니다.

 

만약 TypeScript와 React를 함께 사용하고 싶다면, 제일 먼저 해야할 것은 prop types를 어떻게 TypeScript로 정의하는 지 알아야 합니다. Vanilla React에서는 prop types 정의가 선택적입니다. 하지만 TypeScript와 함께라면, 암묵적이든 명시적이든 모든 것은 반드시 타입이 정의되어야 합니다.
아래 예시를 통해 Prop types와 TypeScript를 비교해 연결지어 사용해 보세요.

 

원시값 (Primitive types)

  • Prop types
 Example.propTypes = {
   message: PropTypes.string,
   count: PropTypes.number,
   disabled: PropTypes.bool,
   level: PropTypes.symbol,
 }
  • TypeScript
interface Props {
  message: string
  count: number
  disabled: boolean
  level: Symbol
}

 

Special types

  • Prop types
Example.propTypes = {
  error: PropTypes.instanceOf(Error),
  children: PropTypes.node,
  status: PropTypes.oneOf(['inactive', 'inProgress', 'success', 'failed']),
  value: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Error),
  ]),
}
  • TypeScript
interface Props {
  error: Error
  children: React.ReactNode
  status: 'inactive' | 'inProgress' | 'success' | 'failed'
  value: string | number | Error
}

 

배열 & 객체 (Array & object types)

  • Prop types
Example.propTypes = {
  style: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
  person: PropTypes.exact({
    name: PropTypes.string,
    age: PropTypes.number,
    employed: PropTypes.bool,
    status: PropTypes.oneOf([
      'single',
      'dating',
      'engaged',
      'married',
      'divorced',
      'widowed',
      'other',
    ]),
  }),
  names: PropTypes.arrayOf(PropTypes.string),
  items: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number,
      title: PropTypes.string,
      active: PropTypes.boolean,
    }),
  ),
}
  • TypeScript
interface Props {
  style: {
    color: string
    fontSize: number
  }
  person: {
    name: string
    age: number
    employed: boolean
    status:
      | 'single'
      | 'dating'
      | 'engaged'
      | 'married'
      | 'divorced'
      | 'widowed'
      | 'other'
  }
  names: string[]
  items: {
    id: number
    title: string
    active: boolean
  }[]
}
NOTE:
PropTypes.shape()은 객체에 포함될 속성 이외에 추가 속성을 허용하므로 TypeScript의 index 타입과 기술적으로 동등하다. 하지만 일반적으로, 사람들은 PropTypes.exact()의 의미로 이것을 사용합니다.

 

함수 (Function types)

  • Prop types
Example.propTypes = {
  onClick: PropTypes.func,
  onChange: PropTypes.func,
  onSelect: PropTypes.func,
}
  • TypeScript
interface Props {
  onClick: () => void
  onChange: (val: string) => void
  onSelect: (id: string, val: number) => void
}
NOTE:
보이는 것처럼 함수 prop types가 그들의 interface를 정의하지 않는 반면, TypeScript 함수는 명시적으로 매개변수와 return 값을 정의합니다.

 

필수 vs 선택 (Required vs. Optional)

NOTE!
PropTypes에서는 props는 모두 선택적이며, 필수일 경우 .isRequired를 사용해야 합니다.
반면, TypeScript에서는 모든 props는 필수값이며, 만약 선택적일 경우 ?: 를 사용해 나타내야 합니다.
  • Prop types
Example.propTypes = {
  onClick: PropTypes.func,
  onChange: PropTypes.func,
  onSelect: PropTypes.func,
}
  • TypeScript
interface Props {
  onClick: () => void
  onChange: (val: string) => void
  onSelect: (id: string, val: number) => void
}

 

Reference.