Использование интерфейса машинописного текста для определения propType и возврата дочерних ошибок - PullRequest
1 голос
/ 12 июля 2020

Я пытался создать один компонент для рендеринга моего меню на одной странице реакции с помощью TS + React

И этот компонент - это

interface Routes {
    label: string, 
    link: string,
    active: boolean,
}

const Menu: React.FC<Routes[]> = ({routes}) => {
    const [links, setLinks] = useState<Array<Routes>>([
        routes
    ]);

    const handleClick = (key: number) => {
        const activeRoute = links.map((value, index) => {
            if(value.active) {
                value.active = false;
            }
            
            if(index === key) {
                value.active = true
            }

            return value
        })

        setLinks(activeRoute)
    }

    const createMenu = () => links.map((value, index) => {
            let markUp = value.active ?
                <LinkActive href={value.link}>{value.label}</LinkActive> : <Link href={value.link}>{value.label}</Link>
            return (
                <Item key={index} onClick={() => handleClick(index)}>
                    {markUp}
                </Item>
            )
    })

    return (
        <MenuBar>

            <MenuRight>
                <List>
                    {createMenu()}
                </List>
            </MenuRight>
            
            
        </MenuBar>   
    )
}

const Link = styled.a`
    color: #3a3e47;
    display: inline-block;
    height: 100%;
    font-size: 16px;
    text-decoration: none;
    text-transform: uppercase;
    display: flex;
    align-items: center;
    padding: 0 3px; 

    :hover {
        color: #ffaa3b
    };
`

const LinkActive = styled(Link)`
    color: #ffaa3b;
    border-top: 4px solid #ffaa3b;
    font-weight: 700;
`

const MenuBar = styled.div`
    background-color: white;
    box-shadow: 0px 2px 24px 0px rgba(0, 0, 0, 0.15);
    border-radius: 8px;
    width: 752px;
    height: 80px;
    display: flex;
    justify-content: space-between;
    padding: 0 40px;
    position: relative;
`

const MenuRight = styled.div`
    display: flex;
    align-items: center;
    height: 100%;
`

const List = styled.ul`
    list-style-type: none;
    padding: 0;
    height: 100%;
    margin: 0;
    margin-right: 40px;
`

const Item = styled.li`
    display: inline-block;
    height: 100%;
    margin-right: 20px;

    :last-child {
        margin-right: 0;
    }
`


export default Menu; 

И компонент, который его вызывает заключается в том, что:

const BasicPage: React.FC = ({children}) => {
    let routes =  [
        { label: 'Início', link: '/', active: true },
        { label: 'Quem Somos', link: '/quemSomos', active: false},
        { label: 'Contato', link: '/contato', active: false},
    ]
    
    return (
        <Container>
            <Menu routes={routes} />
            {children}
        </Container>
    )
}

const Container = styled.div`
    width: 100%;
`
export default BasicPage

После размещения кода на странице и отправки реквизита на другую страницу для управления состоянием меню у меня есть эта ошибка.

Type '{ routes: { label: string; link: string; active: boolean; }[]; }' is not assignable to type 'IntrinsicAttributes & Routes[] & { children?: ReactNode; }'.
  Property 'routes' does not exist on type 'IntrinsicAttributes & Routes[] & { children?: ReactNode; }'.  TS2322

    12 |     return (
    13 |         <Container>
  > 14 |             <Menu routes={routes} />
       |                   ^
    15 |             {children}
    16 |         </Container>
    17 |     )

Я пытаюсь для принудительного использования типа переменной маршрутов в интерфейсе в коде меню, но не работает.

1 Ответ

1 голос
/ 12 июля 2020

Попробуйте определить свой массив маршрутов, как показано ниже, в компоненте меню.

let routes : Routes[] =  [
    { label: 'Início', link: '/', active: true },
    { label: 'Quem Somos', link: '/quemSomos', active: false},
    { label: 'Contato', link: '/contato', active: false},
]

Для этого вам нужно определить интерфейс вне файла BasicPage и экспортировать его, чтобы импортировать интерфейс здесь.

...