Definitelytyped: react-select: Select.onChange frappe mal (?)

Créé le 28 janv. 2019  ·  12Commentaires  ·  Source: DefinitelyTyped/DefinitelyTyped

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

Je pense que cela devrait être défini comme:

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

Lorsqu'une option est sélectionnée, l'objet d'option brut est envoyé, pas le ValueType de cet objet.

Commentaire le plus utile

Comment utiliser la définition actuelle sans erreurs de compilation ?

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

Il semble que la vérification isArray ne soit plus suffisante car le type n'est pas OptionType | OptionType[] et le script dactylographié ne peut pas le déduire.

Tous les 12 commentaires

J'ai trouvé cela complètement déroutant.

value dans le handle est le tableau des options sélectionnées (lors de l'utilisation de 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 });
}

Le premier argument du gestionnaire onChange ne peut pas simplement être de type OptionType , car il peut être une, plusieurs ou aucune valeur de OptionType .

Voir https://github.com/JedWatson/react-select/issues/2902 pour une discussion plus approfondie sur le gestionnaire onChange en combinaison avec TypeScript.

@rvanlaarhoven -- OP mis à jour pour accepter un seul ou un tableau. IMO, un tableau doit être transmis au gestionnaire, que le select isMulti soit ou non. Nous devrions simplement nous attendre à un tableau et ne pas avoir à vérifier si le paramètre est un tableau. Mais oh bien...

Je suis d'accord avec @JoshMcCullough
Ce serait plus simple si nous n'avions à traiter qu'un seul type de données, dans ce cas, les tableaux.
Si nous utilisons une sélection unique, nous récupérons simplement l'élément unique du tableau, sinon nous travaillons avec le tableau - aucune vérification supplémentaire n'est nécessaire. En même temps, je comprends que ce n'est pas un simple changement lorsqu'il s'agit d'une bibliothèque comme celle-ci.

Le plus gros ennui pour moi est qu'un tableau ou une valeur unique est renvoyé en fonction de la valeur de isMulti . Cela signifie que le système de types doit déjà connaître le type de onChange .

Pourrions-nous faire une sorte d'union ou de typage conditionnel pour résoudre ce problème ? (attention : idées non testées)

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<...>

ou peut-être

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 : après y avoir réfléchi un peu plus, le type est inférable si vous codez en dur isMulti (par exemple <Select isMulti={false} /> mais pas si vous fournissez une déclaration comme <Select isMulti={getValue()} /> , donc cette stratégie ne fonctionnera probablement pas.

Comment utiliser la définition actuelle sans erreurs de compilation ?

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

Il semble que la vérification isArray ne soit plus suffisante car le type n'est pas OptionType | OptionType[] et le script dactylographié ne peut pas le déduire.

J'ai utilisé une assertion de type comme solution de contournement ici :

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

Une interface (Typescript) est-elle disponible pour le multi-valeur undefined, Array<Option>, Option ?

@hoetmaaiers Vous pourriez faire une aide :

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

Pour contourner ce problème, j'ai défini une interface :
interface iOption { label: string; value: string; };

Et puis, coulé le paramètre :
onChange={(option) => myMethod((option as iOption).value) }

l'utilisation de as encontre de l'objectif de l'utilisation de scripts dactylographiés. Qui suis-je censé tirer la valeur d'un

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

sans utiliser as ? la solution de contournement actuelle n'est pas une solution et peut (probablement) conduire à des bogues à l'avenir.

J'ai toujours ce problème et c'est vraiment ennuyeux de faire à chaque onChange (parce que je n'utilise aucune sélection multiple) la conversion vers le type d'option unique ....

Chaque fois que je dois utiliser item => (item as OptionTypeBase).value. Vraiment mauvais.

Cette page vous a été utile?
0 / 5 - 0 notes