打字稿烦人的反应警告道具

时间:2020-06-16 03:36:46

标签: javascript reactjs typescript

一旦我开始在Typescript中使用React,我会发现我不喜欢的一件事是需要为组件声明每个prop。在此之前,我们可以使用{...props},但是现在我必须在接口中声明每个本地props,例如refplaceholderdefaultValue等。

interface InputProps {
  customProp: boolean;
  props: any;
}

const Input = ({ customProp, placeholder, ...props }: InputProps) => { 
  //warning 
  return <input type="text" {...props} />;
};

https://codesandbox.io/s/distracted-burnell-vlt3i?file=/src/App.tsx

我想享受过去的时光,我只需要在接口中声明非本地属性,可能吗?原生道具已通过{... props}

传递

3 个答案:

答案 0 :(得分:2)

import * as React from "react";
import "./styles.css";

interface InputProps {
  customProp: boolean;
  // props: any; // I think it doesn't need to you.
  [key:string]: any;
}

const Input = ({ customProp, placeholder, ...props }: InputProps) => {
  return <input type="text" {...props} />;
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <Input hello="hello" customProp={false} placeholder={"name"} />
    </div>
  );
}

您可以和[key:string]: any一起度过美好的一天。

但是,我不想建议使用[key:string]: any

因为它对typescript没有意义。

,而且我认为,如果您对typescript感到压力,可以改用js

答案 1 :(得分:1)

如果您使用TypeScript,最好的做法是为每个组件严格定义道具的接口/类型别名。对于您的Input组件,正确的接口应为

interface InputProps {
  customProp: boolean;
  placeholder: string;
  // add other props below
}

也就是说,接口和类型别名可以导出,共享和扩展,因此这将减少重复代码的数量。例如,

interface OtherInputProps extends InputProps {
  value: string;
}

当然,您可以执行类似[key:string]: any的操作,但这将完全违反使用TypeScript的目的,因为您实际上忽略了TypeScript的类型检查功能。在这种情况下,t不会太冗长,可以还原为JavaScript。


编辑:刚刚意识到OP正在尝试用其他道具扩展输入道具。在这种情况下,要使用的正确基本类型将是`React.InputHTMLAttributes:

export interface InputProps extends React.InputHTMLAttributes< HTMLInputElement> {
  customProp: boolean;
}

type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
  customProp: boolean;
}

答案 2 :(得分:1)

我想享受过去的时光,我只需要在接口中声明非本地道具,

是的,有可能。 Typescript允许接口从其他接口扩展,因此您可以定义接口以包含输入元素期望的所有内容以及自定义属性:

export interface ExampleProps extends React.HTMLProps<HTMLInputElement> {
  customProp: boolean;
}

const Example: React.FC<ExampleProps> = ({ customProp, placeholder, ...rest }) => {
  const { t } = useTranslation();
  return <input type="text" {...rest} />;
};

有了这个定义,我尝试渲染以下内容是合法的:

const Thing: FC = () => {
  return <Example placeholder="foo" customProp={true} defaultValue="3" />;
};

但是打字稿会指出,例如,如果我无法传递自定义道具,或者是否传递了placholder的对象。