Skip to content
This repository was archived by the owner on Aug 18, 2023. It is now read-only.
This repository was archived by the owner on Aug 18, 2023. It is now read-only.

Using custom image serializer gives a type error #35

Description

@joniramo

I'm creating a blog for myself using Sanity and Vue with TypeScript. Since I encountered some bumps on the road regarding this library, I'd like to let you know and maybe there could be something to improve. I can make a pull request later too if it's necessary. So here's the beef.

I'm not sure if the default block image serializer is supposed to work? Because without making a custom image serializer (as you will see below) the default serializer simply detected that there's an image among my blocks array and emitted an empty image tag into the DOM without any props or content.

But since I did make a custom serializer, the types of sanity-blocks-vue-component doesn't seem to like it very much. See the following simple example:

<template>
  <div>
    <div v-if="post" class="content">
      <h1>{{ post.title }}</h1>
      <SanityBlocks :blocks="blocks" :serializers="serializers" />
    </div>
  </div>
</template>

<script setup lang="ts">
import imageUrlBuilder from "@sanity/image-url";
import { SanityBlocks } from "sanity-blocks-vue-component";
import { defineComponent, h, ref } from "vue";
import type { Ref } from "vue";
import { useRoute } from "vue-router";

import sanity from "../client";

const imageBuilder = imageUrlBuilder(sanity);

const loading = ref(false);
const post: Ref<Record<string, any> | null> = ref(null);

const query = `*[slug.current == $slug] {
  _id,
  title,
  slug,
  body
}[0]
`;

function imageUrlFor(source: any) {
  return imageBuilder.image(source);
}

const serializers = {
  types: {
    image: defineComponent({
      props: ["asset"],
      setup(props) {
        return () =>
          h("img", {
            src: imageUrlFor(props.asset).width(480).url(),
          });
      },
    }),
  },
};


function fetchData() {
  const route = useRoute();
  loading.value = true;
  sanity.fetch(query, { slug: route.params.slug }).then(
    (data) => {
      loading.value = false;
      post.value = data;
    },
    (err) => {
      console.error(error);
      loading.value = false;
    }
  );
}

fetchData();
</script>

The issue comes from the SanityBlocks component's serializer prop. As I pass it my custom serializer it does work, but it gives the following type error:

Type '{ types: { image: DefineComponent<Readonly<{ asset?: any; }>, () => VNode<RendererNode, RendererElement, { [key: string]: any; }>, unknown, {}, {}, ComponentOptionsMixin, ... 5 more ..., { ...; }>; }; }' is not assignable to type 'Partial<Serializers>'.
  Types of property 'types' are incompatible.ts(2322)
types.d.ts(43, 9): 'block' is declared here.
index.d.ts(19, 5): The expected type comes from property 'serializers' which is declared here on type 'IntrinsicAttributes & Partial<{ blocks: Block[]; serializers: Partial<Serializers>; }> & Omit<Readonly<{ blocks: Block[]; serializers: Partial<...>; }> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "blocks" | "serializers">'

I can supress this by setting the const serializer = { ... } as any, but it's not really a long term solution.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions