【问题标题】:Typescript types for Prismic Slices棱镜切片的打字稿类型
【发布时间】:2020-12-27 05:03:27
【问题描述】:

我正在使用 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 的新手,所以语言对我来说有点过时了。

【问题讨论】:

  • Prismic 有类型定义吗?可能已经有一个 Slice 类型。创建一个具有任何通用属性的基本接口“Slice”,并让您的切片组件扩展它。 TextHero extends Slice。然后在输入切片时,您说它们的类型为Slice
  • 这就是问题所在:stackoverflow.com/a/57088282/2445709
  • 你能澄清这些答案吗?绝对看起来这是进入的方式。

标签: javascript reactjs typescript gatsby prismic.io


【解决方案1】:

问题是当您映射const sliceComponents = 时。它缺少签名,因此返回类型隐式为any。 正如错误所说。

你可以通过说你有一个 React 类组件/函数组件的列表来明确说明吗?

const sliceComponentsMap: {
  [key: string]: typeof Component | FunctionComponent;
} 

| 是一个 union 运算符。这表示它可以是这两种类型中的任何一种。


但我认为创建一个扩展 React Component 类的通用切片类会更好。

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} />
  );
});

Check this stack

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 2021-12-07
    • 2019-01-29
    • 2022-08-18
    • 2017-02-01
    • 1970-01-01
    • 2021-12-04
    • 2021-11-26
    • 2020-10-12
    相关资源
    最近更新 更多