React Typescript - 动态类型

IT技术 javascript reactjs typescript types
2021-05-25 02:23:58

是否可以有动态类型?我有一个这样的json

{
  "fieldName": "Some text",
  "type": String,
  "inputType": "text"
},
{
  "fieldName": "Some bool",
  "type": Boolean,
  "inputType": "checkbox
}

基于那个 json 我想渲染这样的字段组件

const Field: React.FC<FieldInterface> = ({ name, type, handler }) => {
  const [value, setValue] = useState<type>()

  const handleOnChane = (e: ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value)
    handler(name, e.target.value)
  }

  return (
    <div>
      <label htmlFor={name}>{name}</label>
      <input
        type={type}
        id={name}
        onChange={handleOnChane}
        value={value}
      ></input>
    </div>
  )
}
export default Field

这是我的界面

export interface FormInterface {
  fields: FieldPropInterface[]
  submitAction: Function
}

export interface FieldPropInterface {
  name: string
  inputType: string
  type: <Here I would like to have something but don't know what>
}

export interface FieldInterface {
  name: string
  type: string
  handler: Function
}

你看,我需要那个类型来设置 useState 钩子变量的类型。有可能这样做吗?

回购链接:https : //github.com/johnathan-codes/react-form-from-json

3个回答

使用替代类型。

export interface FieldPropInterface {
  name: string;
  inputType: string;
  type: Boolean | String;
}

其他响应将起作用,但它们没有利用typescript的全部功能。您想要的是在字段之间建立关系inputTypetype这样的字段{inputType: "checkbox"}必须始终为boolean{inputType: "text"}必须始终为string,依此类推。

下面是如何使用联合类型来做到这一点(你也可以使用地图或条件,但我不会进入)。

type FieldPropInterface = {
    fieldName: string;
} & ({
    type: "string";
    inputType: "text";
} | {
    type: "boolean";
    inputType: "checkbox";
})

您需要更多地阅读HTML 输入元素及其props,因为您希望将复选框与文本输入区别对待。复选框通过一个boolean名为checked而不是value字符串属性来设置它们的值npm 上还有很多包可以让处理表单变得更加容易。

如果您想useState通用,那么您的组件Field应该是通用的。

您还说过您FieldInterface.handler可以是任何类型的Function,但您需要具体说明该功能是什么。

{ handler: (e: ChangeEvent<HTMLInputElement>) => void; }

或者它可以成为一个功能value而不是event不同的设置。

在使用大写名称时,您确定知道自己在做什么String吗?大写名称表示该值是 String 构造函数,而小写表示该值是 a string文档

永远不要使用类型 Number、String、Boolean、Symbol 或 Object 这些类型是指几乎从未在 JavaScript 代码中正确使用的非原始盒装对象。

如果您正在使用这个作为一个标志,只是说“这个值是一个字符串”或“这个值是一个布尔”,你可能会考虑使用文字串"string""boolean",而不是对象的构造函数,但我不知道在哪里以及如何这实际上正在您的代码中使用。

你也可以做这样的事情:

export interface FieldInterface<T> {
  name: string
  type: T
  handler: Function
}

const Field: React.FC<FieldInterface<typeof type>> = ({ name, type, handler }) => {
  const [value, setValue] = useState<type>()

  const handleOnChane = (e: ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value)
    handler(name, e.target.value)
  }

  return (
    <div>
      <label htmlFor={name}>{name}</label>
      <input
        type={type}
        id={name}
        onChange={handleOnChane}
        value={value}
      ></input>
    </div>
  )
}
export default Field