Prismic Slices 的 Typescript 类型
Typescript types for Prismic Slices
我正在使用 Prismic、Gatsby 和 Typescript 构建网站。 Prismic 的部分吸引力在于切片功能,它允许您创建内容编辑者更容易使用的动态内容部分。我有一个名为 SliceZone
的组件,它映射页面上的所有切片:
SliceZone.tsx
import React from 'react';
import { ImageCta } from 'components/slices/call-to-action/image/ImageCta';
import { Columns } from 'components/slices/columns/Columns';
import { ContentBlock } from 'components/slices/content-block/ContentBlock';
import { Embed } from 'components/slices/embed/Embed';
import { TextHero } from 'components/slices/hero/text/TextHero';
import { Slider } from 'components/slices/slider/Slider';
import { Video } from 'components/slices/video/Video';
interface PageSlicesProps {
slices: any;
}
const PageSlices = ({ slices }: PageSlicesProps) => {
const sliceComponents = {
hero: TextHero,
slider: Slider,
content_block: ContentBlock,
video: Video,
columns: Columns,
embed: Embed,
image_call_to_action: ImageCta,
};
return slices.map((slice: any, index: number) => {
const SliceComponent = sliceComponents[slice.type];
if (SliceComponent) {
return <SliceComponent slice={slice} key={`slice-${slice.type}-${index}`} />;
}
});
};
interface SliceZoneProps {
bodyContent: any;
}
export const SliceZone = ({ bodyContent }: SliceZoneProps) => <PageSlices slices={bodyContent.body} />;
我需要正确输入所有内容。但是,我在 SliceComponent
上收到此错误,特别是 sliceComponents[slice.type]
:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ hero: ({ slice }: any) => Element; slider: ({ slice }: any) => Element; content_block: ({ slice }: any) => Element; video: ({ slice }: any) => Element; columns: ({ slice }: any) => Element; embed: ({ slice }: { ...; }) => Element; image_call_to_action: ({ slice }: any) => Element; }'.
我如何创建一个 interface
来适当地输入这个?如果我的问题有点模糊,我很抱歉,我是 React 和 Typescript 的新手,所以到目前为止我对这门语言有点不适应。
问题出在 const sliceComponents =
的映射时。它缺少签名,因此 return 类型隐式为 any
。
正如错误所说。
你可以明确地说你有一个 React class components/function 组件列表吗?
const sliceComponentsMap: {
[key: string]: typeof Component | FunctionComponent;
}
|
是一个 union 运算符。这表示它可以是这些类型中的任何一种。
但我认为创建一个扩展 React 组件的通用切片 class 会更好 class。
export interface sliceCommonProps {
id: string;
}
// Interface for base slice props
export interface sliceProps<P> {
sliceType: string;
sliceData: P & sliceCommonProps; // This "&" joins the 'Generic' param P with the common props interface
}
export interface sliceState {}
// Base class with two generic params (P, S) for passing specific component props and state interfaces later
export class SliceComponent<
P = { [key: string]: any },
S = { [key: string]: any }
> extends Component<sliceProps<P>, sliceState> {}
并让您的切片组件扩展它。
export interface ImageCtaProps {
imageUrl: string;
}
export class ImageCta extends SliceComponent<ImageCtaProps> {
render() {
const { id, imageUrl } = this.props.sliceData;
return <div>{imageUrl}</div>;
}
}
然后当你将它们映射到它们的组件时,你可以说它们是 SliceComponent 类型。编译器现在知道组件应该有正确的道具。
const sliceComponents: {[key: string]: typeof SliceComponent;} = {
hero: TextHero,
...
};
slices.map((slice, index) => {
const SliceComponent = sliceComponents[slice.type];
return <SliceComponent sliceData={slice} sliceType={slice.type} />
);
});
我正在使用 Prismic、Gatsby 和 Typescript 构建网站。 Prismic 的部分吸引力在于切片功能,它允许您创建内容编辑者更容易使用的动态内容部分。我有一个名为 SliceZone
的组件,它映射页面上的所有切片:
SliceZone.tsx
import React from 'react';
import { ImageCta } from 'components/slices/call-to-action/image/ImageCta';
import { Columns } from 'components/slices/columns/Columns';
import { ContentBlock } from 'components/slices/content-block/ContentBlock';
import { Embed } from 'components/slices/embed/Embed';
import { TextHero } from 'components/slices/hero/text/TextHero';
import { Slider } from 'components/slices/slider/Slider';
import { Video } from 'components/slices/video/Video';
interface PageSlicesProps {
slices: any;
}
const PageSlices = ({ slices }: PageSlicesProps) => {
const sliceComponents = {
hero: TextHero,
slider: Slider,
content_block: ContentBlock,
video: Video,
columns: Columns,
embed: Embed,
image_call_to_action: ImageCta,
};
return slices.map((slice: any, index: number) => {
const SliceComponent = sliceComponents[slice.type];
if (SliceComponent) {
return <SliceComponent slice={slice} key={`slice-${slice.type}-${index}`} />;
}
});
};
interface SliceZoneProps {
bodyContent: any;
}
export const SliceZone = ({ bodyContent }: SliceZoneProps) => <PageSlices slices={bodyContent.body} />;
我需要正确输入所有内容。但是,我在 SliceComponent
上收到此错误,特别是 sliceComponents[slice.type]
:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ hero: ({ slice }: any) => Element; slider: ({ slice }: any) => Element; content_block: ({ slice }: any) => Element; video: ({ slice }: any) => Element; columns: ({ slice }: any) => Element; embed: ({ slice }: { ...; }) => Element; image_call_to_action: ({ slice }: any) => Element; }'.
我如何创建一个 interface
来适当地输入这个?如果我的问题有点模糊,我很抱歉,我是 React 和 Typescript 的新手,所以到目前为止我对这门语言有点不适应。
问题出在 const sliceComponents =
的映射时。它缺少签名,因此 return 类型隐式为 any
。
正如错误所说。
你可以明确地说你有一个 React class components/function 组件列表吗?
const sliceComponentsMap: {
[key: string]: typeof Component | FunctionComponent;
}
|
是一个 union 运算符。这表示它可以是这些类型中的任何一种。
但我认为创建一个扩展 React 组件的通用切片 class 会更好 class。
export interface sliceCommonProps {
id: string;
}
// Interface for base slice props
export interface sliceProps<P> {
sliceType: string;
sliceData: P & sliceCommonProps; // This "&" joins the 'Generic' param P with the common props interface
}
export interface sliceState {}
// Base class with two generic params (P, S) for passing specific component props and state interfaces later
export class SliceComponent<
P = { [key: string]: any },
S = { [key: string]: any }
> extends Component<sliceProps<P>, sliceState> {}
并让您的切片组件扩展它。
export interface ImageCtaProps {
imageUrl: string;
}
export class ImageCta extends SliceComponent<ImageCtaProps> {
render() {
const { id, imageUrl } = this.props.sliceData;
return <div>{imageUrl}</div>;
}
}
然后当你将它们映射到它们的组件时,你可以说它们是 SliceComponent 类型。编译器现在知道组件应该有正确的道具。
const sliceComponents: {[key: string]: typeof SliceComponent;} = {
hero: TextHero,
...
};
slices.map((slice, index) => {
const SliceComponent = sliceComponents[slice.type];
return <SliceComponent sliceData={slice} sliceType={slice.type} />
);
});