首页 > 解决方案 > 显示不同类型问题的组件失败类型保护

问题描述

我的类型保护是type问题中属性的值。例如,radiovs text

interface BaseQuestionType {
  label?: string
}
export type RadioQuestionType = BaseQuestionType & {
  type: 'radio'
}
export type TextQuestionType = BaseQuestionType & {
  type: 'text' | 'textarea'
}
export type QuestionType =
  | RadioQuestionType
  | TextQuestionType

在使用它时,Typescript 抱怨RadioQuestionType被分配给TextQuestionType. 我希望它能够处理通过 any QuestionType

  <Question
    question={QUESTION_MAP[currentQuestionId] as QuestionType} // ERROR HIGHLIGHTS THIS LINE
  />
  // ...
interface BaseQuestionPropsType<TAnswerMap> {
  question: QuestionType
}
type TextQuestionPropsType<TAnswerMap> = BaseQuestionPropsType<TAnswerMap> & {
  question: TextQuestionType
}

type RadioQuestionPropsType<TAnswerMap> = BaseQuestionPropsType<TAnswerMap> & {
  question: RadioQuestionType
}
type PropsType<TAnswerMap> =
  | RadioQuestionPropsType<TAnswerMap>
  | TextQuestionPropsType<TAnswerMap>

type TAnswerMap = Record<string, unknown>
const Question: React.FC<PropsType<TAnswerMap>> = props => { /* ... */ }

这是完整的 Typescript 错误:

Types of property 'question' are incompatible.
      Type 'QuestionType' is not assignable to type 'TextQuestionType'.
        Type 'RadioQuestionType' is not assignable to type 'TextQuestionType'.
          Type 'RadioQuestionType' is not assignable to type '{ type: "textarea" | "text"; }'.
            Types of property 'type' are incompatible.
              Type '"radio"' is not assignable to type '"textarea" | "text"'.ts(2322)

标签: reactjstypescript

解决方案


问题出在PropsType<TAnswerMap>界面上。在您的问题组件中,您可以改用它:

const Question: React.FC<BaseQuestionPropsType<TAnswerMap>> = props => { /* ... */ }

BaseQuestionPropsType已经适应QuestionType了该领域question

如果存在唯一的“文字”类型来区分它们,编译器只能在联合中的两种类型之间做出决定。否则,它将无法这样做,您必须容纳联合中的所有类型。从文档中阅读歧视性工会


推荐阅读