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.
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 ?
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.
Commentaire le plus utile
Comment utiliser la définition actuelle sans erreurs de compilation ?
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.