reactjs 条件 typescript 解释和错误

lstz6jyr  于 2022-12-18  发布在  React
关注(0)|答案(1)|浏览(98)

我想知道是否有人能告诉我这个 typescript 是如何工作的,并解释每种类型的语法和类型是如何赋值的。我在第46行得到一个错误:

(onChange(options[e.target.selectedIndex])

错误:
类型为“Value”的参数|价值|undefined“不能赋给”Value“类型的参数。”Value“可以用与”Value“无关的任意类型示例化|价值|未定义'. ts(2345)
组件:

type Allowed = string | number;

type BaseProps<Value> = {
  value: Value;
  onChange: (newValue: Value) => void;
  options: readonly Value[];
  mapOptionToLabel?: (option: Value) => Allowed;
  mapOptionToValue?: (option: Value) => Allowed;
};

// mappers required only in certain cirumstances
// we could get fancier here and also not require if `Value` has `value`/`label` properties
type Props<Value> = Value extends Allowed
  ? BaseProps<Value>
  : Required<BaseProps<Value>>;

// type guard function checks value and refines type
const isAllowed = (v: any): v is Allowed =>
  typeof v === "string" || typeof v === "number";

function CustomSelect<Value>({
  value,
  onChange,
  options,
  mapOptionToLabel,
  mapOptionToValue
}: Props<Value>) {
  const toLabel = (option: Value): Allowed => {
    if (mapOptionToLabel) {
      return mapOptionToLabel(option);
    }
    // if our props are provided correctly, this should never be false
    return isAllowed(option) ? option : String(option);
  };

  const toValue = (option: Value): Allowed => {
    if (mapOptionToValue) {
      return mapOptionToValue(option);
    }
    return isAllowed(option) ? option : String(option);
  };

  const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    onChange(options[e.target.selectedIndex]);
  };

  return (
    <select value={toValue(value)} onChange={handleChange}>
      {options.map((value) => (
        <option value={toValue(value)} key={toValue(value)}>
          {toLabel(value)}
        </option>
      ))}
    </select>
  );
}

用法:

const SelectUser = () => {
  const users: User[] = [
    {
      id: 1,
      name: "John"
    },
    {
      id: 322,
      name: "Susan"
    },
    {
      id: 57,
      name: "Bill"
    }
  ];

  const [user, setUser] = React.useState(users[0]);

  return (
    <div>
      <div>Value: {JSON.stringify(user)}</div>

      <CustomSelect
        value={user}
        onChange={setUser}
        options={users}
        // has an error if no mapOptionToLabel is provided!
        // I don't know why the type for user isn't automatic
        mapOptionToLabel={(user: User) => user.name}
        mapOptionToValue={(user: User) => user.id}
      />
    </div>
  );
};


以下是对其他人提出的stackoverflow问题的回答,以供参考:
How to type a custom React select component using TypeScript?

des4xlb0

des4xlb01#

确保该值不为空

if(options[e.target.selectedIndex]){
       onChange(options[e.target.selectedIndex]);
}

相关问题