reactjs - نوع 'Requireable' قابل اختصاص به نوع 'Validator<"horizontal" | "vertical" | undefined>' نیست


کد

import * as React from 'react';
import * as PropTypes from 'prop-types';

interface ILayoutProps {
  dir?: 'horizontal' | 'vertical'
};

const Layout: React.FunctionComponent<ILayoutProps> = (props) => {
  return (
    <div>
      {props.children}
    </div>
  );
};

Layout.defaultProps = {
  dir: 'horizontal'
};
Layout.propTypes = {
  dir: PropTypes.oneOf(['horizontal', 'vertical'])
};
export default Layout;

پیغام خطا

TS2322: Type '{ dir: Requireable<string>; }' is not assignable to type 'ValidationMap<ILayoutProps>'.
  Types of property 'dir' are incompatible.
    Type 'Requireable<string>' is not assignable to type 'Validator<"horizontal" | "vertical" | undefined>'. 

چطور باید Layout.propTypes را تعریف کنم؟

پاسخ شماره ۱

یک نوع جدید بسازید و به آن ارجاع دهید.

import * as React from 'react';
import * as PropTypes from 'prop-types';

type Direction = 'horizontal' | 'vertical'

interface ILayoutProps {
  dir?: Direction;
};

const Layout: React.FunctionComponent<ILayoutProps> = (props) => {
  return (
    <div>
      {props.children}
    </div>
  );
};

Layout.defaultProps = {
  dir: 'horizontal',
};

Layout.propTypes = {
  dir: PropTypes.oneOf<Direction>(['horizontal', 'vertical']),
};

export default Layout;

من روش تایپ قوی را دوست دارم. شاید شما هم بتوانید این کد را در نظر بگیرید.

import * as React from 'react';
import * as PropTypes from 'prop-types';

export enum Direction {
  Horizontal = 'horizontal',
  Vertical = 'vertical',
}

interface ILayoutProps {
  dir?: Direction;
};

const Layout: React.FunctionComponent<ILayoutProps> = (props) => {
  return (
    <div>
      {props.children}
    </div>
  );
};

Layout.defaultProps = {
  dir: Direction.Horizontal,
};

Layout.propTypes = {
  dir: PropTypes.oneOf<Direction>([
    Direction.Horizontal,
    Direction.Vertical,
  ]),
};

export default Layout;

طرز استفاده :

import Layout, { Direction } from './Layout';
// ...
<Layout dir={Direction.Horizontal}></Layout>

پاسخ شماره ۲

بعد از بررسی مسائل دیگر، این باید کار کند:

import * as React from 'react';
import * as PropTypes from 'prop-types';

const tuple = <T extends string[]>(...args: T) => args;

const DIR = tuple('horizontal', 'vertical')

interface ILayoutProps {
  dir?: typeof DIR[number];
};

const Layout: React.FunctionComponent<ILayoutProps> = (props) => {
  return (
    <div>
      {props.children}
    </div>
  );
};

Layout.defaultProps = {
  dir: 'horizontal',
};

Layout.propTypes = {
  dir: PropTypes.oneOf(DIR),
};

export default Layout;