Eu acredito que isso deve ser definido como:
onChange?: (value: OptionType | OptionType[], action: ActionMeta) => void;
Quando uma opção é selecionada, o objeto de opção bruto é enviado, não o ValueType
desse objeto.
Eu achei isso totalmente confuso.
value
no identificador é a matriz de opções selecionadas (ao usar 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 });
}
O primeiro argumento do manipulador onChange
não pode ser simplesmente do tipo OptionType
, pois pode ser um, vários ou nenhum valor de OptionType
.
Consulte https://github.com/JedWatson/react-select/issues/2902 para uma discussão mais aprofundada sobre o manipulador onChange em combinação com TypeScript.
@rvanlaarhoven - Atualizado OP para aceitar um ou array. IMO, um array deve ser passado para o manipulador independentemente de o select isMulti
. Devemos apenas esperar um array e não ter que verificar se o parâmetro é um array. Mas tudo bem ...
Eu concordo com @JoshMcCullough
Seria mais fácil se tivéssemos que lidar apenas com um único tipo de dados, neste caso, Arrays.
Se estivermos usando seleção única, apenas pegamos o único item do array, caso contrário, trabalharemos com o array - sem verificações extras necessárias. Ao mesmo tempo, entendo que não seja uma mudança simples ao lidar com uma biblioteca como esta.
O maior aborrecimento para mim é que um array ou valor único é retornado dependendo do valor de isMulti
. Isso significa que o sistema de tipos já deve saber o tipo de onChange
.
Podemos fazer algum tipo de união ou tipagem condicional para resolver isso? (aviso: ideias não testadas)
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 talvez
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;
EDITAR: depois de pensar um pouco mais sobre isso, o tipo é deduzível se você codificar isMulti
(por exemplo, <Select isMulti={false} />
mas não se você fornecer uma declaração como <Select isMulti={getValue()} />
, então esta estratégia provavelmente não funcionará.
Como faço para usar a definição atual sem erros do compilador?
Parece que a verificação isArray não é mais suficiente, pois o tipo não é OptionType | OptionType[]
e o typescript não pode inferi-lo.
Usei uma declaração de tipo como uma solução alternativa aqui:
props.onChange((v as YourOptionTypeHere).value);
Há uma interface (Typescript) disponível para o valor múltiplo undefined, Array<Option>, Option
?
@hoetmaaiers Você poderia fazer um ajudante:
type Nullable<T> = T | null | undefined;
Como solução alternativa, defini uma interface:
interface iOption { label: string; value: string; };
E então, lançou o parâmetro:
onChange={(option) => myMethod((option as iOption).value) }
usar as
anula todo o propósito de usar o texto digitado. Quem sou eu para tirar o valor de um
option: ValueType<{value :string, label: string}>
sem usar as
? a solução alternativa atual não é uma solução e pode (provavelmente irá) levar a bugs no futuro.
Ainda estou tendo esse problema e é realmente irritante fazer em cada onChange (porque não estou usando nenhuma seleção múltipla) para converter para o tipo de opção única ....
Sempre que devo usar item => (item como OptionTypeBase) .value. Muito ruim.
Comentários muito úteis
Como faço para usar a definição atual sem erros do compilador?
Parece que a verificação isArray não é mais suficiente, pois o tipo não é
OptionType | OptionType[]
e o typescript não pode inferi-lo.