类型“typeof Row”不可分配给类型“ComponentType<ListChildComponentProps<any>> & ReactNode”。 TS27

Posted

技术标签:

【中文标题】类型“typeof Row”不可分配给类型“ComponentType<ListChildComponentProps<any>> & ReactNode”。 TS2769【英文标题】:Type 'typeof Row' is not assignable to type 'ComponentType<ListChildComponentProps<any>> & ReactNode'. TS2769 【发布时间】:2021-10-29 05:54:12 【问题描述】:

我正在使用react-window 组合一个无限滚动列表,并且遇到打字稿构建错误。我已经搜索了堆栈溢出并修复了其他一些以前的错误,但我无法修复最后一个。

codesandbox 中的代码如下: https://codesandbox.io/s/pedantic-leakey-bw5fv?file=/src/App.tsx

与此处链接中的代码副本相同:

import  PureComponent  from "react";
import  FixedSizeList as List  from "react-window";
import InfiniteLoader from "react-window-infinite-loader";
import AutoSizer from "react-virtualized-auto-sizer";

const LOADING = 1;
const LOADED = 2;
let itemStatusMap: any = ;

const isItemLoaded = (index: number) => !!itemStatusMap[index];
const loadMoreItems = (
  startIndex: number,
  stopIndex: number
): Promise<void> => 
  for (let index = startIndex; index <= stopIndex; index++) 
    itemStatusMap[index] = LOADING;
  
  return new Promise((resolve) =>
    setTimeout(() => 
      for (let index = startIndex; index <= stopIndex; index++) 
        itemStatusMap[index] = LOADED;
      
      resolve();
      console.log(Object.keys(itemStatusMap).length);
    , 10)
  );
;

interface IRecipeProps 
  index: number;
  style: any;


interface IRecipeState 

class Row extends PureComponent<IRecipeProps, IRecipeState> 
  render() 
    const  index, style  = this.props;
    let label;
    if (itemStatusMap[index] === LOADED) 
      label = `Row $index`;
     else 
      label = "Loading...";
    
    return (
      <div className="ListItem" style=style>
        label
      </div>
    );
  


export default function App() 
  return (
    <AutoSizer>
      ( height, width ) => (
        <InfiniteLoader
          isItemLoaded=isItemLoaded
          itemCount=50
          loadMoreItems=loadMoreItems
        >
          ( onItemsRendered, ref ) => (
            <List
              className="List"
              height=height
              itemCount=50
              itemSize=30
              onItemsRendered=onItemsRendered
              ref=ref
              width=width
            >
              Row
            </List>
          )
        </InfiniteLoader>
      )
    </AutoSizer>
  );

还有错误:

Failed to compile

/home/user/code/frontend/src/components/Table/table2.tsx
TypeScript error in /home/user/code/frontend/src/components/Table/table2.tsx(72,15):
No overload matches this call.
  Overload 1 of 2, '(props: FixedSizeListProps<any> | Readonly<FixedSizeListProps<any>>): FixedSizeList<any>', gave the following error.
    Type 'typeof Row' is not assignable to type 'ComponentType<ListChildComponentProps<any>> & ReactNode'.
      Type 'typeof Row' is not assignable to type 'ComponentClass<ListChildComponentProps<any>, any>'.
        Construct signature return types 'Row' and 'Component<ListChildComponentProps<any>, any, any>' are incompatible.
          The types of 'props' are incompatible between these types.
            Type 'Readonly<IRecipeProps> & Readonly< children?: ReactNode; >' is not assignable to type 'Readonly<ListChildComponentProps<any>> & Readonly< children?: ReactNode; >'.
              Property 'data' is missing in type 'Readonly<IRecipeProps> & Readonly< children?: ReactNode; >' but required in type 'Readonly<ListChildComponentProps<any>>'.
  Overload 2 of 2, '(props: FixedSizeListProps<any>, context: any): FixedSizeList<any>', gave the following error.
    Type 'typeof Row' is not assignable to type 'ComponentType<ListChildComponentProps<any>> & ReactNode'.  TS2769

    70 |               width=width
    71 |             >
  > 72 |               Row
       |               ^
    73 |             </List>
    74 |           )
    75 |         </InfiniteLoader>

【问题讨论】:

【参考方案1】:

您只需将data 属性添加到Row 组件属性即可。

import React,  PureComponent  from "react";
import  FixedSizeList as List  from "react-window";
import InfiniteLoader from "react-window-infinite-loader";
import AutoSizer from "react-virtualized-auto-sizer";

const LOADING = 1;
const LOADED = 2;
let itemStatusMap: any = ;

const isItemLoaded = (index: number) => !!itemStatusMap[index];
const loadMoreItems = (
    startIndex: number,
    stopIndex: number
): Promise<void> => 
    for (let index = startIndex; index <= stopIndex; index++) 
        itemStatusMap[index] = LOADING;
    
    return new Promise((resolve) =>
        setTimeout(() => 
            for (let index = startIndex; index <= stopIndex; index++) 
                itemStatusMap[index] = LOADED;
            
            resolve();
            console.log(Object.keys(itemStatusMap).length);
        , 10)
    );
;

interface IRecipeProps 
    index: number;
    style: any;
    data: Array<unknown> // you need to add `data` property


class Row extends PureComponent<IRecipeProps> 
    render() 
        const  index, style  = this.props;
        let label;
        if (itemStatusMap[index] === LOADED) 
            label = `Row $index`;
         else 
            label = "Loading...";
        
        return (
            <div className="ListItem" style=style>
                label
            </div>
        );
    


export default function App() 
    return (
        <AutoSizer>
            ( height, width ) => (
                <InfiniteLoader
                    isItemLoaded=isItemLoaded
                    itemCount=50
                    loadMoreItems=loadMoreItems
                >
                    ( onItemsRendered, ref ) => (
                        <List
                            className="List"
                            height=height
                            itemCount=50
                            itemSize=30
                            onItemsRendered=onItemsRendered
                            ref=ref
                            width=width
                        >
                            Row
                        </List>
                    )
                </InfiniteLoader>
            )
        </AutoSizer>
    );

Playground

【讨论】:

以上是关于类型“typeof Row”不可分配给类型“ComponentType<ListChildComponentProps<any>> & ReactNode”。 TS27的主要内容,如果未能解决你的问题,请参考以下文章

反应类型错误“不可分配给'从不'类型的参数”

类型 '' 不可分配给类型 '() =>

类型“”不可分配给类型“JwtConfig”

类型“XX”不可分配给类型“YY”。 'XX' 可分配给'YY' 类型的约束,但'YY' 可以被实例化

打字稿 - 字符串'不可分配给类型'FC

类型“null”不可分配给类型“元素”.ts(2345)