【问题标题】:Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes类型“{}”不可分配给类型“IntrinsicAttributes & IntrinsicClassAttributes”
【发布时间】:2018-06-22 18:04:58
【问题描述】:

我目前正在制作一个简单的反应应用程序。 这是我的index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
  <App />,
  document.getElementById('root') as HTMLElement
);
registerServiceWorker();

这里有我的app.tsx

    import * as React from 'react';
import SearchBar from '../containers/price_search_bar';

interface Props {
  term: string;
}

class App extends React.Component<Props> {

  // tslint:disable-next-line:typedef
  constructor(props) {
    super(props);
    this.state = {term: '' };
  }

  render() {
    return (
      <div className="App">
        <div className="App-header">
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          this is my application.
        </p>
        <div>
            <form>
            <SearchBar term={this.props.term} />
            </form>
        </div>
      </div>
    );
  }
}

export default App;

还有我的搜索栏容器:

    import * as React from 'react';

interface Props {
    term: string;
}

// tslint:disable-next-line:no-any
class SearchBar extends  React.Component<Props> {

    // tslint:disable-next-line:typedef
    constructor(props) {
        super(props);
        this.state = { term: '' };
    }

    public render() {
        return(
            <form>
                <input 
                    placeholder="search for base budget"
                    className="form-control"
                    value={this.props.term}
                />
                <span className="input-group-btn" >
                    <button type="submit" className="btn btn-secondary" >
                        Submit
                    </button>
                </span>

            </form>
        );
    }
}

export default SearchBar;

最后我有我的tsconfig.json:

{
  "compilerOptions": {
    "outDir": "build/dist",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": false,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "node_modules/@types"
    ],
    "noUnusedLocals": true
  },
  "exclude": [
    "node_modules",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}

我在错误之后不断收到不同的错误,当我修复一个错误时,另一个错误又出现了,我不确定我做了什么让它表现得像这样。 这是最新的错误:

./src/index.tsx
(7,3): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{ children?: ReactNode; }> & Reado...'.
  Type '{}' is not assignable to type 'Readonly<Props>'.
    Property 'term' is missing in type '{}'.

我试图通过修改我的tsconfig.json 来修复它,但仍然出现相同的错误,我做错了什么以及为什么打字稿会这样。我对此很陌生,通过这个例子,我试图了解 react 是如何一起工作的。

【问题讨论】:

  • 这里为什么需要{} React.Component&lt;Props, {}&gt;
  • @brandNew 我变成了void,也是object,但是一样!
  • 只通过 Props 而没有其他任何东西会发生什么?
  • @brandNew class App extends React.Component&lt;Props&gt; { 也返回与以前相同的错误!
  • 当你通过any?

标签: json reactjs typescript


【解决方案1】:

这里的问题不在于您的 tslint 设置。看下面的代码sn -p:

interface SearchBarProps {
  term: string;
  optionalArgument?: string;
}

interface SearchBarState{
  something: number;
}

class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
  constructor(props: SearchBarProps){
    super(props);

    this.state = {
      something: 23
    };
  }

  render() {
    const {something} = this.state;
    return (
      <div>{something}</div>
    )
  }
}

class SearchBar extends React.Component&lt;SearchBarProps, SearchBarState&gt; {SearchBarPropsSearchBarState 中分别表示组件SearchBar 的预期道具类型和状态类型。使用 typescript 时必须提供 propTypes 和 stateType。
您可以通过使用关键字any 来避免给出类型,但如果您真的想利用使用打字稿,我强烈建议您不要遵循这种“邪恶”的道路。在您的情况下,您似乎没有指定状态类型并使用它,修复将解决此问题。

编辑 1
在接口SearchBarProps中,optionalArgument成为一个可选参数,因为我们在它前面添加了一个问号?,所以&lt;SearchBar term='some term' /&gt;即使你没有明确传递optionalArgument也不会显示任何错误。 希望这能解决您的问题!

【讨论】:

  • 感谢您的回答,但是如果我使用这个容器而不是另一个容器,我仍然面临同样的错误。
  • 等等,添加了类似 &lt;SearchBarPrice term="s"/&gt; 的内容,它确实有效!
  • 当然,如果你遗漏了一些强制参数,它会显示错误。如果您需要可选参数,我将在原始答案中添加如何实现此目的的代码。如果它回答了您的问题,您可以接受答案。
  • SN,您应该接受上述答案之一作为已接受的答案,因为它们确实回答了您的问题。
  • @S.N 如果正确解决了您的问题,请接受答案
【解决方案2】:

刚刚遇到同样的问题。

您在 App 类的 Prop 接口上定义了名为 term 的成员,但您在创建 App 元素时没有提供值。

尝试以下方法:

ReactDOM.render(<App term="Foo" />, document.getElementById('root') as HTMLElement);

【讨论】:

    【解决方案3】:

    我也遇到了同样的问题。添加以下代码以使用 .tsx 组件。

    export interface Props {
      term: string;
    }
    

    export type Props = {
      term ?: string;
    }
    

    我不知道确切的原因,但我认为 typescript 在编译阶段会标记类型错误。让我知道它是否适合你。

    【讨论】:

      【解决方案4】:

      我通过声明一个完全传递给组件的对象解决了很多“不可分配给类型'IntrinsicAttributes & IntrinsicClassAttributes”类型的错误(Microsoft closed issue)。

      在 OP 的示例中,不要使用 term={this.props.term},而是使用 {...searchBarProps} 使其工作:

      render() {
        const searchBarProps = { // make sure all required component's inputs/Props keys&types match
          term: this.props.term
        }
        return (
          <div className="App">
            ...
            <div>
                <form>
                <SearchBar {...searchBarProps} />
                </form>
            </div>
          </div>
        );
      }
      

      【讨论】:

      • 天哪,我已经想了好几天了。你是一个救生员。
      • @ZunaibImtiaz 挖掘Typescript's checker.ts 它可能会起作用,因为不需要执行分配给intrinsicAttributes 的块,因为没有明确的 JsxAttributes比较该组件的调用(isComparingJsxAttributes 可能是假的)。如果你真的需要找出是否是这种情况,请尝试调试 Typescript 的源代码。
      • 天哪。我希望这不是必需的。
      • 天哪。你是一个救生员!
      • 很遗憾,在 21 年 12 月我仍然需要这样做才能绕过检查器。
      【解决方案5】:

      问题是您没有导出界面,您应该始终导出界面道具。所以:

      export interface Props {
        term: string;
      }
      

      是解决办法。

      【讨论】:

      • 不,他在两个文件上都定义了接口。所以这应该不是问题。
      【解决方案6】:

      您只需正确声明组件类型以包含道具类型:

      interface IMyProps {
          myValue: boolean,
      }
      
      const MyComponent: React.FC<IMyProps> = (props: IMyProps) => {
          ...
      }
      
      export default MyComponent;
      

      那么你可以把它当作:

      import MyComponent from '../MyComponent';
      
      ...
      
      return <MyComponent myValue={true} />
      

      瞧,打字稿很高兴。这样做的好处是 typescript 现在只检查传递它们实际存在于 props 接口中的参数(可以防止拼写错误等)。

      对于标准组件,它类似于(在 Swapnill 的示例中已有的内容):

      class MyComponent extends React.Component<IMyProps, IMyState>{
          constructor(props: IMyProps){}
      }
      export default MyComponent;
      

      【讨论】:

        【解决方案7】:

        我对此并不感到自豪,但考虑到此线程中的其他解决方案,这似乎很公平。

        这个例子展示了@react-native-community/slider 的自定义版本,它具有一些默认属性,但能够从外部接收(和覆盖):

        function CustomSlider(props: SliderProps) {
          return (
            <Slider
              style={{ width: '100%', height: 40, marginTop: 12 }}
              minimumValue={0}
              minimumTrackTintColor="#000000"
              maximumTrackTintColor="#000000"
              {...(props as any)}
            />
          );
        }
        

        【讨论】:

        • 看这个解决方案很痛苦,但就像你说的,就像其他解决方案一样老套——这同样好(或坏):D
        【解决方案8】:

        我不断回到这里,因为 Volar 在我的 Vue 3 组件中引发了类似的错误。解决方案始终是我为道具返回并清空对象,因为我的组件模板为了方便而拥有它,但我没有使用它。

        组件使用时:

        <template>
            <div>
                <MyComponent/> <!-- Squiggly error here -->
            </div>
        </template>
        

        组件:

        export default defineComponent({
            name: 'MyComponent',
            components: {},
            props: {}, // Remove this
            setup() {
                return {};
            },
        });
        

        【讨论】:

          猜你喜欢
          • 2020-05-15
          • 2021-09-11
          • 2018-10-24
          • 1970-01-01
          • 2021-12-03
          • 2022-06-12
          • 2022-01-18
          • 2019-05-12
          • 1970-01-01
          相关资源
          最近更新 更多