繁体   English   中英

类型 'JSX.Element' 不可分配给类型 'Element'

[英]Type 'JSX.Element' is not assignable to type 'Element'

以前有这个构建“构建”,但升级了我的依赖项,现在比以前有更多的构建错误。 一直在运行它们,但我似乎无法解决这个问题。 我已经尝试了多种实现:

  children: Element[];
  Element: JSX.Element;

我已经从这一行中删除了JSX.Elementconst VideoSlider: React.FC<Props> = ({ content }) => {希望能解决这个问题,但我不确定..

我真的不知道打字稿所以任何帮助将不胜感激,因为我想重新构建这个版本..

错误:

╰─ yarn run build
yarn run v1.22.10
$ next build
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
warn  - Minimum recommended TypeScript version is v4.3.2, older versions can potentially be incompatible with Next.js. Detected: 3.9.10
Failed to compile.

./components/VideoSlider/index.tsx:194:9
Type error: No overload matches this call.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<"div", any, { selectSVG: any; selectBackgroundImage: any; selectVerticalOrientation: any; backgroundSVG: unknown; backgroundImage: unknown; children: Element[]; Element: Element; }, never, "div", "div">): ReactElement<...>', gave the following error.
    Type 'JSX.Element' is not assignable to type 'Element'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<"div", any, { selectSVG: any; selectBackgroundImage: any; selectVerticalOrientation: any; backgroundSVG: unknown; backgroundImage: unknown; children: Element[]; Element: Element; }, never, "div", "div">): ReactElement<...>', gave the following error.
    Type 'JSX.Element' is not assignable to type 'Element'.

  192 |         selectVerticalOrientation={content.selectVerticalOrientation}
  193 |       >
> 194 |         <FirstSlider>
      |         ^
  195 |           <div className="first-slider background-image-slider">
  196 |             <Slider
  197 |               asNavFor={nav2}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

组件/.tsx 文件:

/* eslint-disable react/jsx-props-no-spreading */
import React, { useState, useRef, useEffect } from "react";
import Slider from "react-slick";
import { Props } from "./interface";
import Video from "../Video";
import {
  VideoSliderComp,
  SliderArrows,
  FirstSlider,
  VideoCopy,
  Slider2Container,
  Slider3Container,
  SliderButtonComp,
  MissingImage,
  ImageContainer,
} from "./styled";
import Layout from "../Layout";
import TextBlock from "../TextBlock";
import { serializers } from "../serializer";
import client from "../../lib/sanityClient";
import imageUrlBuilder from "@sanity/image-url";
import { SanityImageSource } from "@sanity/image-url/lib/types/types";
import MiniTitleComp from "../MiniTitle";

const VideoSlider: React.FC<Props> = ({ content }) => {
  const [nav1, setNav1] = useState(null);
  const [nav2, setNav2] = useState(null);
  const [nav3, setNav3] = useState(null);
  const slider1 = useRef(null);
  const slider2 = useRef(null);
  const slider3 = useRef(null);

  useEffect(() => {
    setNav1(slider1.current);
    setNav2(slider2.current);
    setNav3(slider3.current);
  }, []);

  const gotoNext = () => {
    slider1.current.slickNext();
  };

  const gotoPrev = () => {
    slider1.current.slickPrev();
  };

  const Button = (props: {
    func?: any;
    text?: string;
    first?: boolean;
    last?: boolean;
    right?: boolean;
  }) => {
    const { func, text, first, last } = props;
    return (
      <SliderButtonComp
        first={first}
        last={last}
        role="button"
        className="arrow-btn prev"
        onClick={func}
      >
        <div className="button-container">
          <span className="button">{text}</span>
        </div>
      </SliderButtonComp>
    );
  };

  const renderArrows = (i: string | any[]) => {
    if (i.length > 1) {
      return (
        <SliderArrows className="slider-arrow">
          <Button first text="Previous" func={gotoPrev} />
          <Button last text="Next" func={gotoNext} right />
        </SliderArrows>
      );
    }
  };

  const renderInfo = (slide: {
    videoTitle:
      | boolean
      | React.ReactChild
      | React.ReactFragment
      | React.ReactPortal;
    videoDescription: any;
  }) => {
    return (
      <>
        <h2>{slide.videoTitle}</h2>
        <TextBlock
          props={slide.videoDescription}
          blocks={slide.videoDescription}
          serializers={serializers}
          imageOptions={{
            width: 500,
            height: 500,
          }}
        />
      </>
    );
  };

  const settings = {
    customPaging: function () {
      return <div className="dot"></div>;
    },
    dotsClass: "slick-dots slick-thumb",
  };

  const checkSlideCountRenderDots = (count: string | any[]) => {
    if (count.length > 1) {
      return true;
    } else {
      return false;
    }
  };

  function SvgMissingImage(
    props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
  ) {
    return (
      <MissingImage>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          data-name="Layer 1"
          viewBox="0 0 100 100"
          {...props}
        >
          <path d="M57.21 27.558h22.997L57.21 8.032v19.526z" />
          <path d="M59.813 73.568H7.359V9.138h42.104v21.356a4.812 4.812 0 004.81 4.811H78.36v22.24a21.103 21.103 0 011.847-.086 21.036 21.036 0 013.007.22v-23.5a3.734 3.734 0 00-3.734-3.733H56.487a2.165 2.165 0 01-2.166-2.165V8.013a3.734 3.734 0 00-3.733-3.734H4.559A2.06 2.06 0 002.5 6.34v70.03a2.06 2.06 0 002.06 2.058h54.678a20.933 20.933 0 01.575-4.859z" />
          <circle cx={41.062} cy={36.333} r={4.276} />
          <path d="M66.474 62.602L59.797 50.04a1.234 1.234 0 00-1.777-.446l-8.762 5.875a1.234 1.234 0 01-1.865-.656l-2.797-8.897a1.234 1.234 0 00-1.649-.77l-7.163 2.96a1.234 1.234 0 01-1.484-.435l-4.694-6.736a1.234 1.234 0 00-2.14.203l-11.777 26.4a1.234 1.234 0 001.128 1.737h44.528a21.086 21.086 0 015.129-6.673zM80.207 61.134A17.293 17.293 0 1097.5 78.427a17.293 17.293 0 00-17.293-17.293zm-2.919 7.833a2.924 2.924 0 013.204-2.908 3.005 3.005 0 012.633 3.03v10.354a2.919 2.919 0 01-5.837 0zm2.919 21.842a3.007 3.007 0 113.007-3.007 3.007 3.007 0 01-3.007 3.007z" />
        </svg>
      </MissingImage>
    );
  }

  const imageOrVideo = (props: { videoSliderBuilder: any }) => {
    return content.videoSliderBuilder.map(
      (
        slide: {
          selectContentType: string;
          image: any;
          videoUrl: string;
          selectVideoType: string;
          video: any;
          video2: any;
        },
        index: string
      ) => {
        if (slide.selectContentType === "images") {
          let url = urlFor(slide.image).url();
          if (url === null) {
            return <SvgMissingImage />;
          } else {
            return <img key={"imgfromVideoSliderBuilder" + index} src={url} />;
          }
        } else if (slide.selectContentType === "video") {
          return (
            <div key={"video-slide" + index}>
              <Video
                type="slider"
                key={"video" + index}
                videoUrl={slide.videoUrl}
                selectVideoType={slide.selectVideoType}
                videoSliderFile={[slide.video, slide.video2]}
                playing={slide.selectVideoType}
              />
            </div>
          );
        }
      }
    );
  };

  // Get a pre-configured url-builder from your sanity client
  const builder = imageUrlBuilder(client);

  // Then we like to make a simple function like this that gives the
  // builder an image and returns the builder for you to specify additional
  // parameters:
  function urlFor(source: SanityImageSource) {
    return builder.image(source);
  }

  return (
    <>
      <VideoSliderComp
        key={content.videoSlider2Title}
        selectVerticalOrientation={content.selectVerticalOrientation}
      >
        <FirstSlider>
          <div className="first-slider background-image-slider">
            <Slider
              asNavFor={nav2}
              ref={slider1}
              slidesToShow={1}
              fade={true}
              arrows={false}
              speed={1000}
              focusOnSelect={false}
              accessibility={false}
            >
              {content.videoSliderBuilder.map(
                (slide: {
                  backgroundSVG: any;
                  backgroundImage: any;
                  selectSVG: boolean;
                  selectBackgroundImage: React.Key;
                }) => {
                  console.log("slide:", slide);
                  const svgUrl = urlFor(slide.backgroundSVG).url();
                  const backgroundImageUrl = urlFor(
                    slide.backgroundImage
                  ).url();

                  if (
                    slide.selectSVG === true &&
                    slide.backgroundSVG !== undefined &&
                    backgroundImageUrl !== undefined
                  ) {
                    return (
                      <>
                        <div className="crest-container">
                          <img src={svgUrl ? svgUrl : null} />
                        </div>
                        <ImageContainer
                          className="imageContainer"
                          selectBackgroundImage={slide.selectBackgroundImage}
                        >
                          <img
                            src={backgroundImageUrl ? backgroundImageUrl : null}
                          />
                        </ImageContainer>
                      </>
                    );
                  } else if (
                    slide.selectSVG === false &&
                    backgroundImageUrl !== undefined
                  ) {
                    return (
                      <ImageContainer
                        key={slide.selectBackgroundImage}
                        selectBackgroundImage={slide.selectBackgroundImage}
                      >
                        <img
                          src={backgroundImageUrl ? backgroundImageUrl : null}
                        />
                      </ImageContainer>
                    );
                  } else {
                    return null;
                  }
                }
              )}
            </Slider>
          </div>
          <Layout>
            <div className="content-container">
              <Slider2Container
                selectVerticalOrientation={content.selectVerticalOrientation}
                selectOrientation={content.videoSliderBuilder}
                className="second-slider video-content-slider"
              >
                <MiniTitleComp title={content.videoSlider2Title} />
                <Slider
                  asNavFor={nav3}
                  ref={slider2}
                  slidesToShow={1}
                  swipeToSlide={true}
                  focusOnSelect={false}
                  arrows={false}
                  dots={checkSlideCountRenderDots(content.videoSliderBuilder)}
                  {...settings}
                >
                  {imageOrVideo(content)}
                </Slider>
                {renderArrows(content.videoSliderBuilder)}
              </Slider2Container>
              <Slider3Container
                selectOrientation={content.selectOrientation}
                className="third-slider further-info-slider"
                selectVerticalOrientation={content.selectVerticalOrientation}
              >
                <Slider
                  asNavFor={nav1}
                  ref={slider3}
                  slidesToShow={1}
                  swipeToSlide={true}
                  focusOnSelect={true}
                  arrows={false}
                  dots={false}
                  fade={true}
                  speed={1000}
                  accessibility={false}
                >
                  {content.videoSliderBuilder.map(
                    (slide: any, index: string) => {
                      return (
                        <div
                          key={"videoSlideBuilder" + index}
                          className="further-info-slider__slide"
                        >
                          <VideoCopy>{renderInfo(slide)}</VideoCopy>
                        </div>
                      );
                    }
                  )}
                </Slider>
              </Slider3Container>
            </div>
          </Layout>
        </FirstSlider>
      </VideoSliderComp>
    </>
  );
};

export default VideoSlider;

styled.tsx / 样式组件:

import styled from "styled-components";

const renderOverlay = (prop: boolean) => {
  let css: string;
  if (prop === true) {
    css = "";
  } else if (prop === false) {
    css = null;
  }
  return css;
};

const renderVerticalOrientation = (prop: string) => {
  let css: string;
  if (prop === "top") {
    css = "flex-start";
  } else if (prop === "center") {
    css = "center";
  } else if (prop === "bottom") {
    css = "flex-end";
  }
  return css;
};

export const MiniTitle = styled.p`
  margin-bottom: 20px;
  text-align: left;
  font-size: 14px;
  background: #333333;
  color: #cecece;
  padding: 4px 8px;
  display: inline-flex;
  align-self: flex-start;
`;

export const ImageContainer = styled.div<{ selectBackgroundImage: any }>`
  position: relative;
  &::after {
    content: "";
    background: #151515;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: ${(props: { selectBackgroundImage: any }) =>
      props.selectBackgroundImage ? "0.666" : null};
  }
`;

export const FirstSlider = styled.div<{
  selectSVG: any;
  selectBackgroundImage: any;
  selectVerticalOrientation: any;
  backgroundSVG: unknown;
  backgroundImage: unknown;
  children: Element[];
  Element: JSX.Element;
}>`
  height: 100vh;
  width: 100%;
  object-fit: contain;
  position: relative;
  margin-bottom: 100px;
  .crest-container {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1;
    img {
      object-fit: cover;
      height: 100%;
      opacity: 0.855;
      transform: scale(1);
    }
  }
  .first-slider {
    height: 100%;
    .slick-slider,
    .slick-list {
      height: 100%;
    }
    img {
      width: 100%;
    }
    position: relative;
    &::after {
      content: ${(props: { selectSVG: any }) => (props.selectSVG ? "" : null)};
      content: ${(props: { selectBackgroundImage: any }) =>
        props.selectBackgroundImage ? "" : null};
      background: #151515;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      opacity: 1.888;
    }
    .slick-slide {
      position: relative;
      &:after {
        content: ${(props: { selectSVG: any }) =>
          props.selectSVG ? renderOverlay(props.selectSVG) : null};
        content: ${(props: { selectBackgroundImage: any }) =>
          props.selectBackgroundImage
            ? renderOverlay(props.selectBackgroundImage)
            : null};

        background: #151515;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        opacity: 1.888;
      }
    }
  }

  @media only screen and (max-width: 1000px) {
    height: auto;
    overflow: hidden;

    .first-slider {
      .slick-slide {
        height: 100vh;
        height: 100%;
        div,
        img {
          height: 100%;
        }
      }
    }
  }
`;

export const SliderContainer = styled.div`
  .second-slider,
  .third-slider {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
`;

export const MissingImage = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  svg {
    width: 33.333% !important;
    fill: #e62117;
  }
`;

export const Slider2Container = styled.div<{
  selectVerticalOrientation: any;
  selectOrientation: any;
}>`
  display: flex;
  flex-direction: column;
  justify-content: center;

  justify-content: ${(props: { selectVerticalOrientation: any }) =>
    props.selectVerticalOrientation
      ? renderVerticalOrientation(props.selectVerticalOrientation)
      : null};

  grid-area: content;
  grid-area: ${(props: { selectOrientation: any }) =>
    props.selectOrientation ? "additional" : "content"};
`;

export const Slider3Container = styled(SliderContainer)<{
  selectOrientation: any;
  selectVerticalOrientation: any;
}>`
  display: flex;
  flex-direction: column;

  grid-area: additional;
  grid-area: ${(props: { selectOrientation: any }) =>
    props.selectOrientation ? "additional" : "content"};
  justify-content: ${(props: { selectVerticalOrientation: any }) =>
    props.selectVerticalOrientation
      ? renderVerticalOrientation(props.selectVerticalOrientation)
      : null};
  .slick-slider {
    width: 100%;
  }
`;

export const VideoSliderComp = styled.div<{
  selectVerticalOrientation?: any;
  selectBackgroundImage?: any;
}>`
  div {
    &:focus {
      outline: none !important;
    }
  }
  .slick-dots {
    position: absolute;
    bottom: -40px;
    width: 100%;
    width: auto;
    left: 0;
    li {
      height: initial;
      width: initial;
    }
    z-index: 3;
    .dot {
      background: transparent;

      background: #969696;
      border: 1px solid var(--nice-dark);
      border: none;
      padding: 3px;
      border-radius: 100%;
      transform: scale(0.9333);
    }
    .slick-active .dot {
      background: white;
      transform: scale(1);
    }
  }

  .layout {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    left: 50%;
    transform: translate(-50%, 0);
  }

  .content-container {
    height: 100%;
    width: 100%;

    display: grid;
    grid-template-columns: 50% 50%;
    grid-template-rows: auto;
    grid-template-areas:
      "content additional"
      "content additional";
  }

  .second-slider {
    grid-area: content;
    height: 100%;
    width: 100%;
    z-index: 2;
    .slick-list {
      overflow: hidden;
    }
    .slick-initialized .slick-slide {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 60%;
      overflow: hidden;
      opacity: 0;
      transition: opacity 1s ease;
      transition-delay: 0.2s;
      div {
        width: 100% !important;
      }
    }
    .slick-slide.slick-active {
      opacity: 1;
      transition: opacity 1s ease;
      transition-delay: 0.1s;
    }
    iframe,
    video {
      filter: drop-shadow(0px 4px 0px #333333);
      transition: all 0.666s ease-in 0.1s;
      &:hover {
        filter: drop-shadow(0 4px 0 #484848);
      }
    }
    video {
      height: initial;
    }
  }

  .third-slider {
    grid-area: additional;
    color: white;
    align-items: center;
    z-index: 4;
  }

  .further-info-slider__slide {
    height: auto;
    display: flex !important;
    align-items: center;
    width: 100%;
    overflow-y: scroll;

    h2 {
      display: inline-block;
      position: relative;
    }
  }

  .player-wrapper {
    position: relative;
    padding-top: 56.25%; /* 720 / 1280 = 0.5625 */
  }

  .react-player {
    position: absolute;
    top: 0;
    left: 0;
    height: 100% !important;
  }

  @media only screen and (max-width: 1000px) {
    .background-image-slider {
      position: absolute;
      top: 0;
      left: 0;
    }

    .layout {
      position: relative;
    }

    .further-info-slider__slide {
      height: auto;
      width: 100%;
    }

    .content-container {
      display: flex;
      flex-direction: column;
    }

    .second-slider {
      overflow: initial;
      margin-bottom: 50px;
    }
  }

  @media only screen and (max-width: 1000px) {
    .further-info-slider__slide {
      align-items: flex-start;
    }
  }
`;

export const VideoCopy = styled.div`
  padding: 1em;
  padding-left: 3em;
  padding-right: 3rem;
  width: 95%;
  margin: 0 auto;

  @media only screen and (max-width: 1000px) {
    padding: 0;
    width: 100%;
  }
`;

export const SliderButtonComp = styled.div<{ first: any; last: any }>`
  position: relative;
  svg {
    opacity: 1;
    transition: all 0.333s ease-in 0.1s;
  }
  .button-container {
    display: flex;
    flex-direction: row;
    align-items: center;
  }

  span {
    padding-left: ${(props: { first: any }) => (props.first ? "0" : "3px")};
    padding-right: ${(props: { last: any }) => (props.last ? "0" : "3px")};
  }
  &:hover {
    .button-container {
      span {
        opacity: 1;
      }
      svg {
        opacity: 1;
      }
    }
  }
`;

export const SliderArrows = styled.div`
  grid-area: content;
  position: absolute;
  bottom: -60px;
  width: 100%;
  position: relative;

  display: flex;
  height: auto;
  color: white;
  color: var(--nice-dark);
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  z-index: 2;
  padding: 0;

  .arrow-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: all 1s ease;
    img {
      width: 30px;
    }
    span {
      opacity: 0.8;
      transition: all 0.333s ease-in-out;
    }
    &:hover {
      span {
        color: #f9f9f9;
      }
    }
  }
  .prev {
    img {
      transform: rotate(-90deg);
    }
  }
  .next {
    img {
      transform: rotate(-270deg);
    }
  }

  @media only screen and (max-width: 1000px) {
    bottom: 0;
  }
`;

从我从您的问题中了解到的,您正在尝试将类型功能组件( JSX.Element )分配给一个数组( Element[] )。

尝试:

children: Element[];
Element: Array;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM