Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript support #5

Closed
blieque opened this issue Aug 9, 2018 · 10 comments
Closed

TypeScript support #5

blieque opened this issue Aug 9, 2018 · 10 comments
Labels
enhancement New feature or request

Comments

@blieque
Copy link

blieque commented Aug 9, 2018

The title mostly says it all. Type definitions for Prismic would be great for TypeScript projects. Sorry if this error is actually relates to prismic-javascript or prismic-dom.

TS2339: Property '$prismic' does not exist on type 'Vue'.

@lesharris
Copy link

It seems prismic is placing a low priority on this issue for some reason. Until WipeAir's PR gets accepted or primsic otherwise resolves this you can get types for this.$prismic by creating a prismic.d.ts file in your project and populating the following into it:

import { getApi } from 'prismic-javascript'
import { DefaultClient } from 'prismic-javascript/d.ts/client'

import Vue from 'vue'

type ThenArg<T> = T extends Promise<infer U> ? U : T
type PrismicAPIPromise = ReturnType<typeof getApi>
type PrismicAPI = ThenArg<PrismicAPIPromise>

type ElementType =
  | 'heading1'
  | 'heading2'
  | 'heading3'
  | 'heading4'
  | 'heading5'
  | 'heading6'
  | 'paragraph'
  | 'preformatted'
  | 'strong'
  | 'em'
  | 'list-item'
  | 'o-list-item'
  | 'group-list-item'
  | 'group-o-list-item'
  | 'image'
  | 'embed'
  | 'hyperlink'
  | 'label'
  | 'span'

type Elements = { [key in ElementType]: string }

type HTMLSerializer<T> = (type: ElementType, element: any, text: string | null, children: T[], index: number) => T

interface RichText {
  Elements: Elements
  asHtml(richText: any, linkResolver?: (doc: any) => string, serializer?: HTMLSerializer<string>): string
  asText(richText: any, joinString?: string): string
}

interface Link {
  url(link: any, linkResolver?: (doc: any) => string): string
}

interface VuePrismic {
  endpoint: string
  linkResolver: (doc: any) => string
  htmlSerializer: HTMLSerializer<string>
  client: DefaultClient
  richTextAsPlain: (field: string) => string
}

type PrismicVue<T> = VuePrismic & T

declare module 'vue/types/vue' {
  interface Vue {
    $prismic: PrismicVue<PrismicAPI>
  }
}

I really like Prismic but I don't understand why proper typescript support is not a priority for them.

@blieque
Copy link
Author

blieque commented May 21, 2019

Thanks for this. I just saw your PR from March too. I also rebuilt their Vue components. I'll see if I can get their support to nudge this along.

@peterDijk
Copy link

Hi,
We're a year later now, and this is still open.
@lesharris thanks for the types, I've made a custom d.ts file with this in it, with at the end (I'm using it in NuxtJS)

declare module '@nuxt/types' {
  export interface Context {
    $prismic: PrismicVue<PrismicAPI>
  }
}

To use the NuxtJS prismic module I have to use it like $prismic.api.getSingle ....
In your types I would have to use it without .api in between.
I'm not that good with typescript yet that I know how to change this, but I'm going to try and will post here when succeeded

@peterDijk
Copy link

I've changed type PrismicAPI to: type PrismicAPI = { api: ThenArg<PrismicAPIPromise> }

@lennartzellmer
Copy link

lennartzellmer commented Nov 8, 2020

I still feel like a beginner with typescript too but I am posting my solution anyway ;)
I followed this practice for enabling it in my nuxt project: https://typescript.nuxtjs.org/cookbook/plugins.html#iii-combined-inject
Thanks for pointing me in this direction @peterDijk - My final ~/types/prismic.d.ts file looks like that:

// File: ~/types/prismic.d.ts

import ResolvedApi from 'prismic-javascript/types/ResolvedApi'
import { DefaultClient } from 'prismic-javascript/types/client'

type ThenArg<T> = T extends Promise<infer U> ? U : T
type PrismicAPIPromise = Promise<ResolvedApi>
type PrismicAPI = { api: ThenArg<PrismicAPIPromise> }

type ElementType =
  | 'heading1'
  | 'heading2'
  | 'heading3'
  | 'heading4'
  | 'heading5'
  | 'heading6'
  | 'paragraph'
  | 'preformatted'
  | 'strong'
  | 'em'
  | 'list-item'
  | 'o-list-item'
  | 'group-list-item'
  | 'group-o-list-item'
  | 'image'
  | 'embed'
  | 'hyperlink'
  | 'label'
  | 'span'

type Elements = { [key in ElementType]: string }

type HTMLSerializer<T> = (
  type: ElementType,
  element: any,
  text: string | null,
  children: T[],
  index: number
) => T

interface RichText {
  Elements: Elements
  asHtml(
    richText: any,
    linkResolver?: (doc: any) => string,
    serializer?: HTMLSerializer<string>
  ): string
  asText(richText: any, joinString?: string): string
}

interface Link {
  url(link: any, linkResolver?: (doc: any) => string): string
}

interface VuePrismic {
  endpoint: string
  linkResolver: (doc: any) => string
  htmlSerializer: HTMLSerializer<string>
  client: DefaultClient
  richTextAsPlain: (field: string) => string
}

type PrismicVue<T> = VuePrismic & T

declare module 'vue/types/vue' {
  interface Vue {
    $prismic: PrismicVue<PrismicAPI>
  }
}

declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $prismic: PrismicVue<PrismicAPI>
  }
  interface Context {
    $prismic: PrismicVue<PrismicAPI>
  }
}

declare module 'vuex/types/index' {
  interface Store<S> {
    $prismic: PrismicVue<PrismicAPI>
  }
}

@monicaaikorice
Copy link

monicaaikorice commented Nov 9, 2020

@lennartzellmer, this is awesome! I had to add the Predicates typings to mine. I just made a Predicates.ts, copied the contents of prismic-javascript/types/Predicates.d.ts to it, and changed to declares to export type PredicateValue and export interface Predicates.

@lennartzellmer
Copy link

I extended my solution by those two lines to improve maintainability:

.
.
.
import Predicates from 'prismic-javascript/types/Predicates'
.
.
.

interface VuePrismic {
  .
  .
  .
  predicates: typeof Predicates
}

@lihbr
Copy link
Member

lihbr commented Nov 16, 2020

Hi!

I recently noticed this long-lasting discussion and I'm glad to see you all figured out different ways to get the typing needed on your Vue.js projects.

I admit, however, that this is still far from ideal; with Vue 3 having an emphasis on TypeScript I'll be looking forward to working on the new major of this kit using TypeScript to provide everyone with proper typing 🙂 (same goes for the @nuxtjs/prismic module)

In the meantime I'll encourage you to use the solution proposed by @lennartzellmer #5 (comment), the interface is not expected to move any time soon. I'll check also with our product team if it's conceivable to add definitions for this version.

@lihbr
Copy link
Member

lihbr commented Mar 12, 2021

Hey everyone, I hope your journey with Vue has been going well!

I'm happy to announce to you all that we started working towards supporting Vue 3 and that we opened a Suggestion Thread for everyone to discuss feedback and improvements that could be made to this kit. As announced previously here providing proper TypeScript support will also be part of this update!

Cheers!

@lihbr lihbr mentioned this issue Aug 20, 2021
@lihbr
Copy link
Member

lihbr commented Feb 24, 2022

First-class TypeScript support has been added as part of our Vue 3 package: @prismicio/vue@3

Our new development kits also follow this new guideline:

After thoughtful consideration, those changes won't be backported to @prismicio/vue@2, our Vue 2 package. This is due partly because of Vue 2 TypeScript limitations, partly because we don't want to introduce breaking changes on our Vue 2 kit while the community is shifting toward Vue 3 being the new default.

Thank you all for your understanding and contributions. We hope you'll enjoy using Prismic with our new Vue 3-ready kit!

@lihbr lihbr closed this as completed Feb 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants