Typescript React:提供多余属性时,道具的联合类型不会显示错误 [英] Typescript React: Union type for props does not display error when providing excess properties

查看:57
本文介绍了Typescript React:提供多余属性时,道具的联合类型不会显示错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对 React 组件的 props 使用联合类型

I am trying to use a union type for the props of a React component

type Props =
  | {
      type: "string"
      value: string
    }
  | {
      type: "number"
      value: number
    }
  | {
      type: "none"
    }

class DynamicProps extends React.Component<Props> {
  render() {
    return null
  }
}

// Ok
const string_jsx = <DynamicProps type="string" value="hello" />

// Error as expected, value should be a string
const string_jsx_bad = <DynamicProps type="string" value={5} />

// Ok
const number_jsx = <DynamicProps type="number" value={5} />

// Error as expcted value should be a number
const number_jsx_bad = <DynamicProps type="number" value="hello" />

// Error as expected, invalid isn't a property on any of the unioned types
const extra = <DynamicProps type="string" value="extra" invalid="what" />

// No error? There should be no value when type="none"
const none_jsx = <DynamicProps type="none" value="This should be an error?" />

// Ok, seems like value has become optional
const none2_jsx = <DynamicProps type="none" />

// Error as expected, value is not present. Value doesn't seem to be made optional all the time
const required = <DynamicProps type="string" />

它似乎部分工作,因为根据 type 道具,有效道具会改变.然而,虽然没有出现在联合中的任何类型上的额外属性将是一个错误,但似乎出现在至少一个联合类型中但不属于基于判别属性的类型不会是错误.

It seems to partially work as depending on the type prop the valid props will change. However, while extra properties that do not appear on any of the types in the union will be an error, it seems that a type that appears in at least one of the unioned types but does not belong based on the discriminant property will not be an error.

我不确定为什么会这样.使用联合类型作为 React 组件的道具是一种反模式吗?

I'm not sure why this is the case. Is it an anti-pattern to be using union types as the props for react components?

推荐答案

当涉及联合时,问题与过度的属性检查有关.您可以在此处阅读类似问题的答案.其要点是对联合的额外属性检查允许任何成员的任何键出现在对象上.我们可以通过引入类型为 never 的额外成员来解决这个问题,以确保具有过多属性的对象不会与特定成员错误地兼容:

The problem has to do with excess property checks when unions are involved. You can read this answer here to a similar question. The gist of it is that excess property checks for unions allows any key of any member to be present on the object. We can get around this by introducing extra members of type never to make sure that the object with excess properties in not wrongly compatible with a particular member:

type Props =
| {
    type: "string"
    value: string
    }
| {
    type: "number"
    value: number
    }
| {
    type: "none"
    }

type UnionKeys<T> = T extends any ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>

class DynamicProps extends React.Component<StrictUnion<Props>> {
    render() {
        return null
    }
}
// error now
const none_jsx = <DynamicProps type="none" value="This should be an error?" />

这篇关于Typescript React:提供多余属性时,道具的联合类型不会显示错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆