簡體   English   中英

在 TypeScript 中將 onChange 值設為沒有類型斷言的泛型類型

[英]Getting onChange value to be of generic type without type assertion in TypeScript

我已經創建了一個帶有選項元素的通用反應組件,如下所示: import * as React from "react";

  export interface Option {
    value: string;
    label: string;
    disabled?: boolean;
  }

  export interface SelectProps<CustomOption extends Option> {
    options: CustomOption[];
    onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
    selectedValue: string;
  }

  export const Select: React.FunctionComponent<SelectProps<Option>> = (props): JSX.Element => {
    const options = props.options.map(o => {
      return (
        <option key={o.value} value={o.value} disabled={o.disabled}>
          {o.label}
        </option>
      );
    });

    return (
      <select onChange={props.onChange} value={props.selectedValue}>
        {options}
      </select>
    );
  };

我正在使用這樣的:

  type OptionValues = "FOO" | "BAR" | "BAZ" | "NO_ANSWER";

  const createSelect = (selectedOption: OptionValues, onChange: (v: OptionValues) => void): JSX.Element => {
    const changeHandler = (event: React.ChangeEvent<HTMLSelectElement>): void => onChange(event.currentTarget.value as OptionValues);
    interface SelectOptions extends Option {
      value: OptionValues;
    }

    const selectProps: SelectProps<SelectOptions> = {
      onChange: changeHandler,
      selectedValue: selectedOption,
      options: [
        {
          value: "FOO",
          label: "foo"
        },
        {
          value: "BAR",
          label: "bar"
        },
        {
          value: "BAZ",
          label: "baz"
        },
        {
          value: "NO_ANSWER",
          label: " -- ",
          disabled: true
        }
      ]
    };
    return <Select {...selectProps} />;
  };

有什么方法可以避免在 changeHandler. event.currentTarget.value as OptionValues 我還看到整個 createSelect 突然變得非常冗長,到處都引用了 OptionValues,但我想沒有辦法解決它。 解決問題的替代方法也受到歡迎。 那就是確保價值是預先確定的類型。

在您的情況下,您實際上需要一個類型保護,因為 typescript 並不那么聰明。

如果您的 Select 組件在內心深處,正是我認為的那樣,它將永遠無法工作。

字體保護

type OptionValues = 'FOO' | 'BAR' | 'BAZ' | 'NO_ANSWER'

const isOptionValue = (value: unknown): value is OptionValues =>
  typeof value === 'string' && ['FOO', 'BAR', 'BAZ', 'NO_ANSWER'].includes(value)

  const createSelect = (selectedOption: OptionValues, onChange: (v: OptionValues) => void): JSX.Element => {
    const changeHandler = (event: React.ChangeEvent<HTMLSelectElement>): void => {
        const value = event.currentTarget.value
        if(isOptionValue(value))
         onChange(value);
    }
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM