簡體   English   中英

當我用返回 Select 的組件替換 Select 時,react-select typescript 無法正常工作

[英]react-select typescript not working properly when I substitute Select with a Component that returns Select

因此,與其直接使用 Select,不如創建一個名為 CustomSelect 的組件,該組件將返回 Select 並預先填充一些屬性。

問題是,現在當我使用帶有屬性isMulti={false}的 CustomSelect 組件時,typescript 不會自動理解OnChange屬性應該是類型

(newValue: SingleValue<IOption>, actionMeta: ActionMeta<IOption>) => void

代替

(newValue: SingleValue<IOption> | MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void

為什么會發生這種情況,有什么好的解決方法嗎?

自定義選擇.tsx

import Select, {
  components,
  OptionProps,
  ValueContainerProps,
  Props as SelectProps,
} from "react-select";
import { IOption } from "../../Table/Types";
import "./CustomSelect.scss";

//type IOption = {
//  value: any;
//  label: string;
//  icon?: string;
//};

const { Option: OptionCointainer, ValueContainer } = components;

function OptionWithIcon(props: OptionProps<IOption>) {
  const {
    label,
    data: { icon },
  } = props;
  return (
    <OptionCointainer {...props} className="selectOption">
      {!!icon && <img src={icon} alt={label} />}
      {label}
    </OptionCointainer>
  );
}

// react-select is buggy when you try to override rendered value component
// children is being used as a workaround
function ValueWithIcon(props: ValueContainerProps<IOption>) {
  const { getValue, children } = props;
  const { label, icon } = getValue()[0];
  return (
    <ValueContainer {...props} className="selectValue">
      <>
        {!!icon && <img src={icon} alt={label} />}
        {label}
        <span className="hiddenAbsolute">{children}</span>
      </>
    </ValueContainer>
  );
}

function CustomSelect(props: SelectProps<IOption>) {
  const { options } = props;
  return (
    <Select
      isDisabled={options ? options.length < 2 : true}
      components={{
        Option: OptionWithIcon,
        ValueContainer: ValueWithIcon,
      }}
      {...props}
    />
  );
}

export default CustomSelect;

過濾器.tsx

      <Select
        id="currencyFrom"
        isMulti={false}
        value={state.fromCurrency}
        // if I hover on change type is (newValue: SingleValue<IOption>, actionMeta: ActionMeta<IOption>) => void
        onChange={onValueChange("fromCurrency")}
        options={someOptions}
        isSearchable={false}
      />
      <CustomSelect
        id="currencyTo"
        isMulti={false}
        value={state.toCurrency}
        // if I hover on change type is (newValue: SingleValue<IOption> | MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void
        onChange={onValueChange("toCurrency")}
        options={someOptions}
        isSearchable={false}
      />

編輯 React Typescript(分叉)

您嘗試適應的SelectProps類型是具有 3 種類型 arguments 的泛型類型( 在此處定義)。 因為您為第一個參數提供了一個類型,所以推理被禁用,另外 2 個 arguments 和 Typescript 將它們設置為默認值。

如果您需要推理工作,您不能提供部分類型 arguments,我可以看到 2 個解決方案:

  • 去掉SelectProps<Option>中的Option參數,同時推斷Option類型
function CustomSelect(props: SelectProps) {
  • 如果您需要強制執行特定的Option類型,請為您的道具創建另一個通用類型,該類型僅采用最后 2 個 arguments 並讓 typescript 推斷這些:
type CustomSelectProps<
    IsMulti extends boolean = boolean,
    Group extends GroupBase<Option> = GroupBase<Option>
> = SelectProps<Option, IsMulti, Group>;

…

function CustomSelect(props: CustomSelectProps) {

此外,因為您希望在使用組件時發生這種類型的推理,所以您還應該使您的組件通用,將相同的邏輯應用於StateManagedSelect組件類型( 在此處定義)。

這為我們提供了以下組件類型定義,使用CustomSelectProps

function CustomSelect<
    IsMulti extends boolean = false,
    Group extends GroupBase<IOption> = GroupBase<IOption>
>(props: SelectProps<IOption, IsMulti, Group>) {

更新了代碼框:您會看到我也必須將相同的邏輯應用於您的其他組件,因為所有類型都相互依賴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM