如何在打字稿3.8中键入相互依赖的Props?

时间:2020-06-08 14:38:30

标签: reactjs typescript typescript-typings

我有一个Table组件,其中包含一组道具,如下所示:

type Props = {
  data: Aray<Object>,
  columns: Array<Column>,
  apiSearch?: boolean,
  fetchData?: (params) => void,
}

const Table = (props: Props) => {
 const onFilterChange = (filter) => {
   if (apiSearch) {
     fetchData(filter); // Getting possibly undefined error here. Is there a way to make typescript understand this function will be present if apiSearch is true??
   }
 };

 return (
   <TableComponent {...props} onFilter={onFilterChange} />
 )
};

我正在尝试以这样的方式键入fetchdata:如果apiSearch为true,并且在其他情况下为可选,则应该是一个函数。

我尝试定义两种类型,例如:

type WithApiSearch = {
  apiSearch: true;
  fetchSearchData: (params: object) => void;
};

type WithoutApiSearch = {
  apiSearch: undefined | false;
};

type Props = CommonProps & (WithApiSearch | WithoutApiSearch);

如果未提供fetchDataapiSearch为true,则不会显示任何错误。我不知道这是否可行,我是Typescript的新手。

1 个答案:

答案 0 :(得分:0)

仅使用条件键:

查看以下playground

type Props = {
  apiSearch: true,
  fetchData: (params: any) => void,
} | {
    apiSearch: false,
    fetchData?: false,
}

const Table = (props: Props) => {}

// Error
Table({
  apiSearch: true,
  fetchData: false,
});

// Ok
Table({
  apiSearch: true,
  fetchData: () => {},
});

// Error
Table({
  apiSearch: false,
  fetchData: () => {},
});

// Ok
Table({
  apiSearch: false,
  fetchData: false,
});

现在混合使用条件键和常规键:

Playground

type ConditionalProps = {
  apiSearch: true,
  fetchData: (params: any) => void,
} | {
  apiSearch: false,
  fetchData?: false,
}

interface PropsBase {
  foo?: string,
  bar?: boolean,
}

type Props = PropsBase & ConditionalProps;

const Table = (props: Props) => {}

Table({
  apiSearch: true,
  fetchData: false,
});

Table({
  apiSearch: true,
  fetchData: () => {},
});

Table({
  apiSearch: false,
  fetchData: () => {},
});

Table({
  apiSearch: false,
  fetchData: false,
});