Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以使用typescript创建一个通用的反应列表组件?_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 是否可以使用typescript创建一个通用的反应列表组件?

Javascript 是否可以使用typescript创建一个通用的反应列表组件?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我正在创建一个列表组件,该组件应该处理要列表的不同对象。但是我找不到渲染该项目的解决方案。 列表需要是通用的,因为我有许多不同的东西要列出,但可能没有办法,我需要创建不同的列表组件来处理每个对象 我得到这个错误: Property 'name' does not exist on type 'string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege'. Property 'name' does no

我正在创建一个列表组件,该组件应该处理要列表的不同对象。但是我找不到渲染该项目的解决方案。 列表需要是通用的,因为我有许多不同的东西要列出,但可能没有办法,我需要创建不同的列表组件来处理每个对象

我得到这个错误:

Property 'name' does not exist on type 'string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege'.
  Property 'name' does not exist on type 'string'.
代码如下:

const GetItem = (
    item: string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege,
    index: number
) => {
    switch (typeof item) {
        case typeof PrivilegeConditionElement:
            return `PrivilegeContionElement ${index}`;
        case typeof Privilege:
            return `Privilege ${index}`;
        case typeof PrivilegeCondition:
            return `PrivilegeContion ${index}`;
        case typeof PrivilegeConditionOperator:
            return item.name; //<===============ERROR when doing this
        default:
            return item;
    }
};

const List: FC<Props> = ({ handelRemove, itemsList }) => (
    <ListWrapper>
        <ul style={{ listStyleType: "none", padding: "0", margin: 0 }}>
            {itemsList.map((item, index) => (
                <DivWithToolTip
                    data-tooltip={item}
                    // eslint-disable-next-line react/no-array-index-key
                    key={index}
                    style={{
                        display: "flex",
                        justifyContent: "row",
                        alignContent: "center",
                        alignItems: "center",
                    }}>
                    <li style={{ marginTop: "10px" }}>{GetItem(item, index)}</li>
                    <PlusButton
                        style={{ marginTop: "10px" }}
                        {...{ addIcon: false }}
                        onClick={() => handelRemove(item)}
                    />
                </DivWithToolTip>
            ))}
        </ul>
    </ListWrapper>
);

interface IListProps {
    handelRemove: (item: string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege) => void;
    itemsList: Array<string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege>;
}
type Props = IListProps;

export default List;
const GetItem=(
项:字符串| PrivilegeConditionOperator | PrivilegeConditionElement | Privilege,
索引:编号
) => {
开关(项目类型){
PrivilegeConditionElement的案例类型:
返回`PrivilegeContionElement${index}`;
特权的案例类型:
返回`Privilege${index}`;
PrivilegeCondition的案例类型:
返回`PrivilegeContion${index}`;
PrivilegeConditionOperator的案例类型:
return item.name;//(
    {itemsList.map((项,索引)=>(
  • {GetItem(item,index)}
  • handelRemove(项目)} /> ))}
); 接口进程{ handelRemove:(项:字符串| PrivilegeConditionOperator | PrivilegeConditionElement | Privilege)=>void; itemsList:数组; } 类型Props=IListProps; 导出默认列表;
我也尝试过这个,但同样的错误是:

<li style={{ marginTop: "10px" }}>{item.name && item}</li>
  • {item.name&&item}

  • 您遇到的问题不是特定于react的问题,而是特定于TypeScript的问题,因为TypeScript编译器抱怨
    GetItem
    函数中的某些内容不是特定于react的

    假设
    PrivilegeConditionOperator
    是一个类,而不是
    接口
    类型
    ,您可以使用
    if…else if…
    语句代替switch和
    instanceof
    代替
    typeof
    ,如下所示:

    const GetItem = (
        item: string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege,
        index: number
    ) => {
            if (item instanceof PrivilegeConditionElement)
                return `PrivilegeContionElement ${index}`;
            else if (item instanceof Privilege)
                return `Privilege ${index}`;
            else if (item instanceof PrivilegeCondition)
                return `PrivilegeContion ${index}`;
            else if (item instanceof PrivilegeConditionOperator)
                return item.name;
            else
                return item;
        
    };
    
    

    拯救通用组件。通过使用通用方法,您实际上可以简化并制作出更广泛使用的组件

    这里的问题是,您正在传入一组不同的类型,但是您的
    getItem
    函数是硬编码的。您应该传入适合所显示类型的
    getItem
    函数

    假设您按如下方式定义了道具界面:

    interface IListProps<T> {
        handleRemove: (item: T) => void;
        itemsList: T[];
        getItem: (v: T, index: number) => string; //pass this function into your component
    }
    

    因此,在同一个列表中,您可以同时渲染不同类型的项?即,并非一个特定渲染列表中的所有元素都属于同一类型?啊,instanceof完成了这个技巧,我只使用了if和no“if else”最后只使用了return。ESlint让我这么做:)。无论如何,谢谢你的帮助!该死的,这看起来很棒,我会试试的!
    const List = <T,>({ handleRemove, itemsList, getItem }: React.PropsWithChildren<IListProps<T>>): JSX.Element => (
        <ListWrapper>
            <ul style={{ listStyleType: 'none', padding: '0', margin: 0 }}>
                {itemsList.map((item, index) => (
                    <DivWithToolTip
                        data-tooltip={item}
                        // eslint-disable-next-line react/no-array-index-key
                        key={index}
                        style={{
                            display: 'flex',
                            justifyContent: 'row',
                            alignContent: 'center',
                            alignItems: 'center',
                        }}
                    >
                        <li style={{ marginTop: '10px' }}>{getItem(item, index)}</li>
                        <PlusButton
                            style={{ marginTop: '10px' }}
                            {...{ addIcon: false }}
                            onClick={() => handleRemove(item)}
                        />
                    </DivWithToolTip>
                ))}
            </ul>
        </ListWrapper>
    );
    
    const [items,setItems] = React.useState([{name:"Christian"}]);
    return <List 
               itemsList = {items} 
               handleRemove = {(item) => setItems(items.filter(v => v != item)} 
               getItem={(v, i) => `${v.name}`} />