Subscribe on changes!

ref type broken for HTMLElement

avatar
Aug 26th 2022

Vue version

3.2.27

Link to minimal reproduction

https://codesandbox.io/s/stoic-lovelace-vjtqk6?file=/src/index.ts

Steps to reproduce

Note the error on line 4 of index.ts.

What is expected?

ref<HTMLElement | null>(null) is assignable to a variable of type Ref<HTMLElement | null>.

What is actually happening?

Type Error:

  Type '{ accessKey: string; readonly accessKeyLabel: string; autocapitalize: string; dir: string; draggable: boolean; hidden: boolean; innerText: string; lang: string; readonly offsetHeight: number; ... 274 more ...; focus: (options?: FocusOptions) => void; }' is not assignable to type 'HTMLElement'.
    The types of 'offsetParent.attributes' are incompatible between these types.
      Type '{ [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: { readonly attributes: ...; ... 162 more ...; readonly assignedSlot: { ...; }; }; readonly length: number; item: (nameOrI...' is not assignable to type 'NamedNodeMap'.
        'number' index signatures are incompatible.
          Type '{ readonly localName: string; readonly name: string; readonly namespaceURI: string; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: { readonly attributes: { [x: number]: ...; readonly length: number; ... 7 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ....' is not assignable to type 'Attr'.
            The types of 'ownerDocument.anchors' are incompatible between these types.
              Type '{ [x: number]: { charset: string; coords: string; download: string; hreflang: string; name: string; ping: string; referrerPolicy: string; rel: string; readonly relList: { [x: number]: string; readonly length: number; ... 13 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ... 300 more ...; username: stri...' is not assignable to type 'HTMLCollectionOf<HTMLAnchorElement>'.
                'number' index signatures are incompatible.
                  Type '{ charset: string; coords: string; download: string; hreflang: string; name: string; ping: string; referrerPolicy: string; rel: string; readonly relList: { [x: number]: string; readonly length: number; value: string; ... 12 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ... 300 more ...; username: stri...' is not assignable to type 'HTMLAnchorElement'.
                    The types of 'shadowRoot.styleSheets' are incompatible between these types.
                      Type '{ [x: number]: { readonly cssRules: { [x: number]: { cssText: string; readonly parentRule: ...; readonly parentStyleSheet: ...; readonly type: number; readonly CHARSET_RULE: number; readonly FONT_FACE_RULE: number; ... 7 more ...; readonly SUPPORTS_RULE: number; }; readonly length: number; item: (index: number) => C...' is not assignable to type 'StyleSheetList'.
                        'number' index signatures are incompatible.
                          Type '{ readonly cssRules: { [x: number]: { cssText: string; readonly parentRule: ...; readonly parentStyleSheet: ...; readonly type: number; readonly CHARSET_RULE: number; readonly FONT_FACE_RULE: number; readonly IMPORT_RULE: number; ... 6 more ...; readonly SUPPORTS_RULE: number; }; readonly length: number; item: (inde...' is not assignable to type 'CSSStyleSheet'.
                            Types of property 'ownerNode' are incompatible.
                              Type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string) => Element | HTMLCollection; namedItem:...' is not assignable to type 'Element | ProcessingInstruction'.
                                Type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string) => Element | HTMLCollection; namedItem:...' is not assignable to type 'Element | ProcessingInstruction'.ts(2322)

System Info

No response

Any additional comments?

Seems like a similar error was fixed in a previous version.

avatar
Aug 29th 2022

This is not an error, it's actually by design. @vue/reactivity is decoupled from any DOM-related types, so it can't treat HTMLElement differently.

@vue/runtime-dom (and by extension, vue itself) does extend the RefUnwrapBailTypes like this to be able to bail from unref-ing HTMLElement:

declare module '@vue/reactivity' {
  export interface RefUnwrapBailTypes {
    runtimeDOMBailTypes: Node | Window
  }
}

So If you want to use the @vue/reactivity package directly, in a DOM environment, you will have to add this type extension yourself.

avatar
Aug 29th 2022

My bad, this error actually happens when using:

import { ref } from 'vue'

I was not aware that this is a different implementation as ref from @vue/reactivity.

Should I open a new issue for this or just update the example?

avatar
Aug 29th 2022

update the example please, because it doesn't happen for me:

Bildschirmfoto 2022-08-29 um 18 44 42
avatar
Aug 29th 2022

Thanks for looking into it! I assume the error happening in our code stems from using jsdom inside our tests. We will investigate further.