类型“JSX.Element”不可分配给类型“元素”
Posted
技术标签:
【中文标题】类型“JSX.Element”不可分配给类型“元素”【英文标题】:Type 'JSX.Element' is not assignable to type 'Element' 【发布时间】:2021-12-06 15:58:19 【问题描述】:以前有这个构建“构建”,但升级了我的依赖项,现在有比以前更多的构建错误。一直在运行它们,但我似乎无法解决这个问题。我尝试了多种实现:
children: Element[];
Element: JSX.Element;
我已经从这一行删除了JSX.Element
:const VideoSlider: React.FC<Props> = ( content ) =>
,希望能解决这个问题,但我不确定..
我真的不知道 Typescript,所以任何帮助将不胜感激,因为我想再次构建这个构建..
错误:
╰─ 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 / styled-components:
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;
`;
【问题讨论】:
我知道当您不完全确定问题时可能会很困难,但是当您的问题更简洁时,您将有更好的机会获得答案/帮助 - 您已经包括大量代码供任何人尝试和破译。 你有没有找到解决这个问题的方法? 【参考方案1】:根据我从您的问题中了解到的情况,您正在尝试将类型功能组件 (JSX.Element
) 分配给数组 (Element[]
)。
试试:
children: Element[];
Element: Array;
【讨论】:
以上是关于类型“JSX.Element”不可分配给类型“元素”的主要内容,如果未能解决你的问题,请参考以下文章
错误 TS2602:JSX 元素隐式具有类型“任何”,因为全局类型“JSX.Element”不存在
输入'元素 | undefined' 不可分配给类型 'ReactElement<any, string | ((道具:任何)