【问题标题】:TypeScript: Type of property incompatible when assigning from generic typeTypeScript:从泛型类型分配时属性类型不兼容
【发布时间】:2021-07-05 01:13:19
【问题描述】:

考虑以下代码:(这里也是示例代码https://codesandbox.io/s/hbtew?file=/src/index.ts

enum Types {TEXT, DATE}

interface TextState {
  type: typeof Types.TEXT
}

interface DateState {
  type: typeof Types.DATE
}

type State = TextState | DateState;

interface GenericProps {
  state: State
}

interface InputProps<AnyState> {
  state: AnyState;
}

function TextInput(props: InputProps<TextState>) {
}

function DateInput(props: InputProps<DateState>) {
}

const props: GenericProps = {state: {type: Types.TEXT}};
/*
Type 'State' is not assignable to type 'TextState'.
  Type 'DateState' is not assignable to type 'TextState'.
    Types of property 'type' are incompatible.
      Type 'Types.DATE' is not assignable to type 'Types.TEXT'
*/
TextInput(props);

const {state} = props;
/*
Type 'State' is not assignable to type 'TextState'.
  Type 'DateState' is not assignable to type 'TextState'
*/
TextInput({state: state});

/* OK */
TextInput({state: {type: Types.TEXT}});

/* OK */
DateInput({state: {type: Types.DATE}});

如您所见,调用 TextInput(props) 时出错。您能否解释一下它是如何出现该错误的以及您将如何修复代码以便调用TextInput(props) 不会出错?目的是能够构造不同的GenericProps,只有type不同,可以传递给TextInput(props)(如果props = {state: {type: Types.TEXT}})或者DateInput(props)(如果props = {state: {type: Types.DATE}}),谢谢!

【问题讨论】:

    标签: reactjs typescript typescript-generics


    【解决方案1】:

    通常您需要“帮助”Typescript 了解您已经验证了道具类型, 因为否则你可能会改变状态类型。

    您可以通过添加如下所示的validateTextProps 函数来解决这个问题:

    function validateTextProps(props: GenericProps): props is InputProps<TextState> {
      return props.state.type === Types.TEXT;
    }
    
    const props: GenericProps = { state: { type: Types.TEXT } };
    if(validateTextProps(props)){
      TextInput(props);
    }
    

    这样 Typescript 就可以理解 props 的类型是正确的,并允许你调用 TextInput(props)。

    【讨论】:

    • 谢谢。但这意味着我必须为每种类型创建这些布尔函数。不是什么好东西,但如果这是唯一的方法,我会接受。您能否建议一种使用switch 而不是if 的方法?
    猜你喜欢
    • 1970-01-01
    • 2019-02-20
    • 2019-09-06
    • 2016-01-23
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    相关资源
    最近更新 更多