Home > Mobile >  Add new interface and prop to imported component
Add new interface and prop to imported component

Time:06-11

I'm trying to import TextField and add inputMode prop from NumberField component. So I added inputMode in the interface and also used ...rest in the TextField in order to receive new props. But currently I'm getting this error:

Type '{ inputMode: "numeric"; onChange: (value: string) => void; value: string; }' is not assignable to type 'IntrinsicAttributes & ITextFieldProps & { children?: ReactNode; }'. Property 'inputMode' does not exist on type 'IntrinsicAttributes & ITextFieldProps & { children?: ReactNode; }'.

I'm not sure what I'm doing wrong. Just trying to add one more prop. Any advice would be appreciated. Source: https://codesandbox.io/s/numberfield-component-ts-wohlok?file=/src/NumberField.tsx:0-686

TextField.tsx

import React, { useState } from "react";

export interface ITextFieldProps {
  type?: "text" | "search";
  onChange?: (value: string) => void;
  required?: boolean;
}

export const TextField: React.FunctionComponent<ITextFieldProps> = React.forwardRef<
  HTMLInputElement,
  ITextFieldProps
>((props, ref) => {
  const { type = "text", onChange, required = true, ...rest } = props;
  const [value, setValue] = useState("");

  function handleChange(e: React.FormEvent<HTMLInputElement>) {
    setValue(e.currentTarget.value);
    onChange?.(e.currentTarget.value);
  }

  return (
    <input
      type={type}
      value={value}
      onChange={handleChange}
      required={required}
      {...rest}
    />
  );
});

NumberField.tsx

import React, { useState } from "react";
import { ITextFieldProps, TextField } from "./TextField";

export interface INumberFieldProps extends ITextFieldProps {
  inputMode?: "numeric";
}

export const NumberField: React.FunctionComponent<INumberFieldProps> = React.forwardRef<
  HTMLInputElement,
  INumberFieldProps
>((props, ref) => {
  const { inputMode = "numeric", onChange } = props;
  const [value, setValue] = useState("");

  function handleChange(value: string) {
    const updatedValue = value.replace(/\D/g, "");
    setValue(updatedValue);
    onChange?.(updatedValue);
  }

  return (
    <TextField inputMode={inputMode} onChange={handleChange} value={value} />
  );
});

CodePudding user response:

Your HTML should conform to standards. inputMode="numeric" is not the right way to make a numeric input. The right way is type="number".

export interface ITextFieldProps {
  type?: "text" | "search" | "number"; // <--- Add "number" here
  onChange?: (value: string) => void;
  required?: boolean;
}

Then in your NumberField.tsx:

import React, { useState } from "react";
import { ITextFieldProps, TextField } from "./TextField";

export interface INumberFieldProps extends ITextFieldProps {
  type?: "number"; // <--- Rename prop
  onChange?: () => void;
}

export const NumberField: React.FunctionComponent<INumberFieldProps> = React.forwardRef<
  HTMLInputElement,
  INumberFieldProps
>((props, ref) => {
  const { type = "number", onChange } = props; // <--- Rename prop
  const [value, setValue] = useState("");

  function handleChange(value: string) {
    const updatedValue = value.replace(/\D/g, "");
    setValue(updatedValue);
    onChange?.(updatedValue);
  }

  return (
    <TextField type={type} onChange={handleChange} value={value} /> // <--- Rename prop
  );
});

This should work, but to further improve the code, you can omit the type in INumberFieldProps altogether, because its value can only ever be number:

import React, { useState } from "react";
import { ITextFieldProps, TextField } from "./TextField";

export interface INumberFieldProps extends ITextFieldProps {
  onChange?: () => void; // <--- Remove `type`
}

export const NumberField: React.FunctionComponent<INumberFieldProps> = React.forwardRef<
  HTMLInputElement,
  INumberFieldProps
>((props, ref) => {
  const { onChange } = props; // <--- Remove `type`
  const [value, setValue] = useState("");

  function handleChange(value: string) {
    const updatedValue = value.replace(/\D/g, "");
    setValue(updatedValue);
    onChange?.(updatedValue);
  }

  return (
    <TextField type="number" onChange={handleChange} value={value} /> // <--- Hard-code `type="number"`
  );
});

CodePudding user response:

inputMode is not contained in the ITextFieldProps interface, so you won't be able to access the property or assign a value to it.

Try adding [key: string]: any; to the ITextFieldProps interface if you don't know explicitly the type that you'll send as a prop like so:

export interface ITextFieldProps {
  type?: "text" | "search";
  onChange?: (value: string) => void;
  required?: boolean;
  [key: string]: any;
}

Then it should work.

Forked Sandbox: Sandbox

  • Related