これは次のように定義する必要があると思います。
onChange?: (value: OptionType | OptionType[], action: ActionMeta) => void;
オプションを選択すると、そのオブジェクトのValueType
ではなく、生のオプションオブジェクトが送信されます。
私はこれが完全に混乱していることに気づきました。
ハンドルのvalue
は、選択されたオプションの配列です( 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 });
}
最初の引数onChange
ハンドラは、単純型にすることはできませんOptionType
、それはどちらかワン、マルチプルかの無い値とすることができるので、 OptionType
。
TypeScriptと組み合わせたonChangeハンドラーの詳細については、 https://github.com/JedWatson/react-select/issues/2902を参照して
@ rvanlaarhoven-単一または配列を受け入れるようにOPを更新しました。 isMulti
選択するかどうかに関係なく、IMO配列をハンドラーに渡す必要があります。 配列を期待するだけで、パラメーターが配列であるかどうかを確認する必要はありません。 しかしまあ...
@JoshMcCulloughに同意します
単一のデータ型(この場合は配列)のみを処理する必要がある場合は、より簡単になります。
単一選択を使用している場合は、配列から単一のアイテムを取得するだけです。それ以外の場合は、配列を操作します。追加のチェックは必要ありません。 同時に、このようなライブラリを扱う場合、これは単純な変更ではないことを理解しています。
私にとって最大の煩わしさは、 isMulti
値に応じて配列または単一の値が返されることです。 これは、型システムがonChange
型をすでに認識している必要があることを意味します。
これを解決するために、ある種の結合または条件付きタイピングを実行できますか? (警告:テストされていないアイデア)
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<...>
多分
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;
編集:これについてもう少し考えた後、 isMulti
をハードコーディングするとタイプは推測できます(たとえば、 <Select isMulti={false} />
ですが、 <Select isMulti={getValue()} />
ようなステートメントを提供する場合は推測できません。したがって、この戦略おそらく動作しません。
コンパイラエラーなしで現在の定義を使用するにはどうすればよいですか?
タイプがOptionType | OptionType[]
ではなく、typescriptがそれを推測できないため、isArrayチェックではもはや十分ではないようです。
ここでは、回避策として型アサーションを使用しました。
props.onChange((v as YourOptionTypeHere).value);
マルチ値undefined, Array<Option>, Option
インターフェイス(Typescript)を使用できますか?
@hoetmaaiersあなたはヘルパーを作ることができます:
type Nullable<T> = T | null | undefined;
回避策として、インターフェイスを定義しました。
interface iOption { label: string; value: string; };
そして、パラメータをキャストしました:
onChange={(option) => myMethod((option as iOption).value) }
as
を使用すると、typescriptを使用する目的全体が無効になります。 私は誰から価値を引き出すことになっていますか
option: ValueType<{value :string, label: string}>
as
を使用せずに? 現在の回避策は解決策ではなく、将来バグにつながる可能性があります(おそらくそうなるでしょう)。
私はまだこの問題を抱えており、(複数選択を使用していないため)すべてのonChangeで単一オプションタイプへのキャストを行うのは本当に面倒です...。
item =>(item as OptionTypeBase).valueを使用する必要があるたびに。 すごく悪い。
最も参考になるコメント
コンパイラエラーなしで現在の定義を使用するにはどうすればよいですか?
タイプが
OptionType | OptionType[]
ではなく、typescriptがそれを推測できないため、isArrayチェックではもはや十分ではないようです。