reactjs - 显示不同类型问题的组件失败类型保护
问题描述
我的类型保护是type
问题中属性的值。例如,radio
vs 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)
解决方案
问题出在PropsType<TAnswerMap>
界面上。在您的问题组件中,您可以改用它:
const Question: React.FC<BaseQuestionPropsType<TAnswerMap>> = props => { /* ... */ }
BaseQuestionPropsType
已经适应QuestionType
了该领域question
。
如果存在唯一的“文字”类型来区分它们,编译器只能在联合中的两种类型之间做出决定。否则,它将无法这样做,您必须容纳联合中的所有类型。从文档中阅读歧视性工会
推荐阅读
- ruby-on-rails - Rails 6 不会自动获取配置更改或新 gem
- vue.js - 在 Vuejs/Laravel 中刷新 JWT 令牌后如何将数据重新发布到服务器
- android - 如何在android中实现可以展开为列表视图的卡片栈视图(类似于iOS群组通知)
- amazon-web-services - 查找我的日志文件发送到 aws 的位置
- ios - SwiftUI - 画布超出屏幕宽度 - 应用被拒绝
- r - R chisq.test 给出不同的 P 值
- javascript - 根据数字的值,将数组中的一个数组(带有字符串和数字)中的字符串推送到新数组
- python - 产生不同结果的时间和日期时间模块
- swift - iOS 13 MPRemoteCommandCenter 在后台模式后断开连接
- http - DirectApiAuthorizationRequired 与 Microsoft Flow 调用 Microsoft Flow