我认为这应该定义为:
onChange?: (value: OptionType | OptionType[], action: ActionMeta) => void;
选择一个选项时,将发送原始选项对象,而不是该对象的ValueType
。
我发现这完全令人困惑。
句柄中的value
是所选选项的数组(使用isMuli
道具时)。
_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
一个值、多个值或没有值。
请参阅https://github.com/JedWatson/react-select/issues/2902以获取有关 onChange 处理程序与 TypeScript 相结合的更深入讨论。
@rvanlaarhoven - 更新 OP 以接受单个或数组。 IMO 无论是否选择isMulti
都应将数组传递给处理程序。 我们应该只期待一个数组,而不必检查参数是否是一个数组。 但是哦,好吧...
我同意@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()} />
这样的语句,则类型是可推断的,所以这个策略可能行不通。
如何在没有编译器错误的情况下使用当前定义?
似乎 isArray 检查不再足够,因为类型不是OptionType | OptionType[]
并且打字稿无法推断它。
我在这里使用了类型断言作为解决方法:
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
违背了使用打字稿的全部目的。 我应该从谁中获取价值
option: ValueType<{value :string, label: string}>
不使用as
? 当前的解决方法不是解决方案,将来可能(可能会)导致错误。
我仍然遇到这个问题,并且在每个 onChange(因为我没有使用任何多选)上执行到单个选项类型的转换真的很烦人....
每次我必须使用 item => (item as OptionTypeBase).value。 特别糟糕。
最有用的评论
如何在没有编译器错误的情况下使用当前定义?
似乎 isArray 检查不再足够,因为类型不是
OptionType | OptionType[]
并且打字稿无法推断它。