【问题标题】:Union type doesn't work with conflicting properties联合类型不适用于冲突的属性
【发布时间】:2021-08-02 21:39:25
【问题描述】:

所以我试图在我正在构建的 React Native 应用程序中组合一些组件,以便它们可以共享逻辑和样式并使其更易于维护。现在,它们之间的唯一区别是它们为 props 扩展的接口和渲染组件的名称。以下是我想要做的简化形式:

interface ISharedInputProps {
    label: string;
    errorText?: string | null;
    isPassword?: boolean;
    hasTextRight?: boolean;
}

export interface IInputProps extends React.ComponentProps<typeof TextInput>, ISharedInputProps {
    inputType: 'input';
}

export interface IMaskedInputProps extends React.ComponentProps<typeof MaskedTextInput>, ISharedInputProps {
    inputType: 'masked';
}

export interface ICurrencyInputProps extends React.ComponentProps<typeof CurrencyInput>, ISharedInputProps {
    inputType: 'currency';
}

const Input: React.FC<IInputProps | IMaskedInputProps | ICurrencyInputProps> = ({
    inputType,
    ...props
}) => {
    // Component logic here
    return (
        // Shared wrapping UI here
        { inputType === 'input' && <TextInput {...props}/> }
        { inputType === 'masked' && <MaskedTextInput {...props}/> }
        { inputType === 'currency' && <CurrencyInput {...props}/> }
        // Shared wrapping UI here
    )
};

export default Input;

但是,一旦我进入 inputType 条件,编译器就会抛出一个错误,因为每种类型之间存在冲突,没有兼容的值(即:“Type '(text: string, rawText: string) => void'不可分配给类型“(文本:字符串)=> void”。输入组件声明上的实际联合类型似乎不会引发错误,只是在初始化内部组件时。删除 IMaskedInputProps 或 ICurrencyInputProps 有效,所以他们之间似乎正在发生冲突。

我的理解是,如果我将 inputType 设置为预定义值(即:'input'),它会自动将 IMaskedInputProps 接口分配给组件,但情况似乎并非如此。有没有办法做我想做的事,而不仅仅是将输入类型更改为React.FC&lt;any&gt; 并在 UI 本身中放置一堆检查?

【问题讨论】:

  • inputType for CurrencyInput 应该是 currency 对吧?您已将其设置为 input
  • @JeffMercado 啊,哎呀,我的错。固定的!它就在应用程序上:P

标签: reactjs typescript


【解决方案1】:

摆脱解构赋值,只需:

const Input: React.FC<IInputProps | IMaskedInputProps | ICurrencyInputProps> = (props) => {
    // Component logic here
    return (
        // Shared wrapping UI here
        { props.inputType === 'input' && <TextInput {...props}/> }
        { props.inputType === 'masked' && <MaskedTextInput {...props}/> }
        { props.inputType === 'currency' && <CurrencyInput {...props}/> }
        // Shared wrapping UI here
    )
};

当你从 props 对象中解构 inputType 时,你正在创建一个类型为 'input' | 'masked' | 'currency' 的全新变量。 TS 不会记住这是来自对象的可区分联合的相同属性。如果您有另一个以相同方式键入但具有不同值的局部变量,您将不会期望能够用它来区分道具,因为它与对象没有关系。

【讨论】:

  • 有趣!将其引用为 props.inputType 似乎可行。好吧,至少这比我想象的要容易!
猜你喜欢
  • 2018-03-28
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
相关资源
最近更新 更多