首页 > 解决方案 > “类型字符串的参数不能分配给自定义类型的参数”的难看问题

问题描述

我有一个有效的打字稿代码,请参阅片段。TS 的问题在于,它将代码声明为错误的消息:

'string' 类型的参数不能分配给 'SetStateAction<"vertical" | 类型的参数 “水平” | “垂直反转” | “水平反转”>'。

我怎样才能把这段代码写得更干净?我考虑过使用类型或枚举,但后来我得到了许多不必要的强制转换,这会降低可读性,并且它变成了意大利面条代码,因为我为此编写了很多代码。

这里的代码:

const directionItems = [
    { key: 0, label: "vertical" },
    { key: 1, label: "horizontal" },
    { key: 2, label: "vertical-reverse" },
    { key: 3, label: "horizontal-reverse" }
  ];

  const [curDirection, setCurDirection] = React.useState<
    "vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse"
  >("vertical");

<DropDown
   items={directionItems}
   defaultSelectedIndex={3}
   onSelectionChange={value =>
   setCurDirection(directionItems[value].label) // <-- this is where the compiler gets angry even if it just works
 }></DropDown>

这里也是使用枚举的方法,但在我看来,这是使用大量代码的方式还是合法的?(使用这种方法编译器没有错误):

enum position {
    "top",
    "bottom",
    "left",
    "right",
    "in-between"
  }

  const buttonPositionItems = [
    { key: 0, label: position[0] },
    { key: 1, label: position[1] },
    { key: 2, label: position[2] },
    { key: 3, label: position[3] },
    { key: 4, label: position[4] }
  ];

  const [curButtonPosition, setButtonPosition] = React.useState<position>(
    position.right
  );

 <DropDown
    items={buttonPositionItems}
    defaultSelectedIndex={3}
    onSelectionChange={value =>
      setButtonPosition(
      (buttonPositionItems[value].label as unknown) as position)
    }
></DropDown>

我现在的解决方案(虽然我没有使用界面..)

export type DirectionType = | "vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse";

const directionItems = [
    { key: 0, label: "vertical" },
    { key: 1, label: "horizontal" },
    { key: 2, label: "vertical-reverse" },
    { key: 3, label: "horizontal-reverse" }
  ];

  const [curDirection, setCurDirection] = React.useState<DirectionType>(
    "vertical"
  );

<DropDown
  onSelectionChange={value =>
     setCurDirection(directionItems[value].label as DirectionType )
     }>/<DropDown>

标签: javascriptreactjstypescriptreact-tsx

解决方案


您可能希望使用接口来提供显式类型,以便 TypeScript 能够识别labeltype "vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse"。例如,您可以使用类型别名

export type LabelType = ("vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse");

export interface DirectionItem {
  key: number;
  label: LabelType;
}

现在,我们可以将接口与您的 React 功能组件一起使用。

const directionItems: DirectionItem[] = [
    { key: 0, label: "vertical" },
    { key: 1, label: "horizontal" },
    { key: 2, label: "vertical-reverse" },
    { key: 3, label: "horizontal-reverse" }
  ];

const [curDirection, setCurDirection] = React.useState<LabelType>("vertical");

推荐阅读