chore: migrate composables to typescript#2497
Conversation
Signed-off-by: Jonas <jonas@freesources.org>
Signed-off-by: Jonas <jonas@freesources.org>
9da1d63 to
34e6c7a
Compare
| interface PageInfoBarElement extends Element { | ||
| currentPage: PageInfo | null | undefined | ||
| canEdit: boolean | ||
| attachmentCount: number | ||
| backlinkCount: number | ||
| } | ||
| const el = readerEl.value?.querySelector<PageInfoBarElement>('page-info-bar') |
There was a problem hiding this comment.
This looks somewhat odd to me. It's an HTML Element, right? And then it has these additional properties of currentPage, canEdit, etc. Seems like we are mixing two things up here.
There was a problem hiding this comment.
PageInfoBar is a custom element and yes, it has these props. At least that's my understanding.
Though it seems like currentPage is not visible in dom structure, only the others are. When you look at the dom structure, it looks like this:
There was a problem hiding this comment.
I did a bit further research on this.
Vue custom elements expose their component props as JavaScript properties on the DOM element. So e.g. using el.attachmentCount = 3 is the correct API usage.
Though only props with simple types (string, number, boolean) get exposed as HTML attributes in the DOM, complex attributes are only available as JavaScript properties. That's why currentPage is not visible in the DOM.
See also https://vuejs.org/guide/extras/web-components.html#passing-dom-properties and https://web.dev/articles/custom-elements-best-practices.
There was a problem hiding this comment.
I moved the interface to the top of the file and changed extends Element to extends HTMLElement as that's indeed more accurate.
There was a problem hiding this comment.
Ah... I see. Could we move the defineCustomElement to the top of the composable then and use PageInfoBarCE to get the type?
const PageInfoBarCE = defineCustomElement(PageInfoBar, { shadowRoot: false })
type PageInfoBarType = InstanceType<typeof PageInfoBarCE>There was a problem hiding this comment.
(Based on https://vuejs.org/guide/typescript/composition-api.html#typing-component-template-refs for typing of refs which also kind of applies here i think.)
There was a problem hiding this comment.
Already merged, but maybe something we can improve later on? I gave your approach a quick test and it didn't work out of the box:
With type PageInfoBarType = InstanceType<typeof PageInfoBarCE> and const el = readerEl.value?.querySelector<PageInfoBarType>('page-info-bar'), el.attachmentCount = attachmentCount.value results in
TS2339: Property
attachmentCountdoes not exist on typeVueElement
max-nextcloud
left a comment
There was a problem hiding this comment.
Thanks a lot for looking into this.
I already commented outside the review as I was not sure if I was gonna finish it. Mostly minor things. One type annotation looks off to me though..
Signed-off-by: Jonas <jonas@freesources.org>
34e6c7a to
3a17cd9
Compare
Follow up for nextcloud#2497 (comment) Signed-off-by: Max <max@nextcloud.com>
🏁 Checklist
npm run lint/npm run stylelint/composer run cs:check)🤖 AI (if applicable)