Definitelytyped: Reagieren-Auswählen: Select.onChange Eingaben falsch (?)

Erstellt am 28. Jan. 2019  ·  12Kommentare  ·  Quelle: DefinitelyTyped/DefinitelyTyped

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f8151b70381d83a6b7e2fc1a44086047144eb9e/types/react-select/lib/Select.d.ts#L166

Ich glaube, dies sollte wie folgt definiert werden:

onChange?: (value: OptionType | OptionType[], action: ActionMeta) => void;

Wenn eine Option ausgewählt wird, wird das Rohoptionsobjekt gesendet, nicht das ValueType dieses Objekts.

Hilfreichster Kommentar

Wie verwende ich die aktuelle Definition ohne Compilerfehler?

Screen Shot 2020-01-10 at 4 50 20 PM

Es scheint, dass die isArray-Prüfung nicht mehr ausreicht, da der Typ nicht OptionType | OptionType[] und Typskript ihn nicht ableiten kann.

Alle 12 Kommentare

Das fand ich total verwirrend.

value im Handle ist das Array der ausgewählten Optionen (bei Verwendung von isMuli prop).

_onTagChange(
  value: ReactSelectTypes.ValueType<{value: number; label: string}>,
  action: ReactSelectTypes.ActionMeta
) {
  console.log('l68:', value, ' action:', action);
  switch(action.action) {
    case 'pop-value':
    case 'remove-value':
  }
  if (value && value.length > 0) {
   e let firstOption = value[0]; // Errors here with: Element implicitly has an 'any' type because type '{ value: number; label: string; } | { value: number; label: string; }[]' has no index signature.

  }
  // this.setState({ categoryTags: tags });
}

Das erste Argument des onChange Handlers kann nicht einfach vom Typ OptionType , da es entweder ein, mehrere oder keine Werte von OptionType .

Eine ausführlichere Diskussion über den onChange-Handler in Kombination mit TypeScript finden Sie unter https://github.com/JedWatson/react-select/issues/2902 .

@rvanlaarhoven -- OP aktualisiert, um Single oder Array zu akzeptieren. IMO sollte ein Array an den Handler übergeben werden, unabhängig davon, ob das select isMulti . Wir sollten nur ein Array erwarten und nicht prüfen müssen, ob der Parameter ein Array ist. Aber naja...

Ich stimme @JoshMcCullough zu
Es wäre einfacher, wenn wir uns nur mit einem einzigen Datentyp befassen müssten, in diesem Fall Arrays.
Wenn wir Single Select verwenden, holen wir einfach das einzelne Element aus dem Array, ansonsten arbeiten wir mit dem Array - es sind keine zusätzlichen Prüfungen erforderlich. Gleichzeitig verstehe ich, dass dies keine einfache Änderung im Umgang mit einer Bibliothek wie dieser ist.

Das größte Ärgernis für mich ist, dass abhängig vom Wert von isMulti ein Array oder ein einzelner Wert zurückgegeben wird. Das bedeutet, dass das Typsystem den Typ von onChange bereits kennen sollte.

Könnten wir eine Art Vereinigung oder bedingte Typisierung durchführen, um dieses Problem zu lösen? (Achtung: ungetestete Ideen)

interface BaseProps<OptionType extends OptionTypeBase = { label: string; value: string }> extends SelectComponentsProps {
  ... /* all existing fields except isMulti and onChange */
}

interface SingleValueProps<...> extends BaseProps<...> {
  isMulti: false;
  onChange: (value: OptionType | null | undefined, action: ActionMeta) => void;
}

interface MultiValueProps<...> extends BaseProps<...> {
  isMulti: true;
  onChange: (value: OptionsType<OptionType> | null | undefined, action: ActionMeta) => void;
}

/* where the props are defined */
selectProps: SingleValueProps<...> | MultiValueProps<...>

oder vielleicht

interface Props<IsMulti extends boolean, OptionType extends OptionTypeBase = { label: string; value: string }> extends SelectComponentsProps {
  ...
  isMulti: IsMulti,
  onChange: (value: ValueType<IsMulti, OptionType>, action: ActionMeta) => void;
  ...
}

export type ValueType<IsMulti extends boolean, OptionType extends OptionTypeBase> =
  (IsMulti extends false ? OptionType : OptionsType<OptionType>) | null | undefined;

EDIT: Nach einigem Nachdenken über diese etwas mehr, ist die Art inferrable wenn Sie hart Code isMulti (zB <Select isMulti={false} /> , aber nicht , wenn Sie bieten eine Aussage wie <Select isMulti={getValue()} /> , so diese Strategie wird wohl nicht funktionieren.

Wie verwende ich die aktuelle Definition ohne Compilerfehler?

Screen Shot 2020-01-10 at 4 50 20 PM

Es scheint, dass die isArray-Prüfung nicht mehr ausreicht, da der Typ nicht OptionType | OptionType[] und Typskript ihn nicht ableiten kann.

Ich habe hier eine Typzusicherung als Workaround verwendet:

props.onChange((v as YourOptionTypeHere).value);

Ist eine Schnittstelle (Typescript) für den Multiwert undefined, Array<Option>, Option verfügbar?

@hoetmaaiers Du

type Nullable<T> = T | null | undefined;

Als Workaround habe ich eine Schnittstelle definiert:
interface iOption { label: string; value: string; };

Und dann den Parameter gecastet:
onChange={(option) => myMethod((option as iOption).value) }

Die Verwendung von as vereitelt den ganzen Zweck der Verwendung von Typoskript. Wem soll ich den Wert aus einem . herausholen?

option: ValueType<{value :string, label: string}>

ohne as ? die aktuelle Problemumgehung ist keine Lösung und kann (wird wahrscheinlich) in Zukunft zu Fehlern führen.

Ich habe dieses Problem immer noch und es ist wirklich ärgerlich, bei jedem onChange (da ich keine Mehrfachauswahl verwende) die Besetzung auf den Einzeloptionstyp durchzuführen ....

Jedes Mal muss ich item => (item als OptionTypeBase).value verwenden. Wirklich schlecht.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen