Reputation: 32048
The following error appears when trying to destructure a form.elements
object:
Type 'HTMLFormControlsCollection' has no property 'x' and no string index signature
// in a class
domRefs: {[key: string]: HTMLFormElement | null} = {
myForm: null
}
onButtonClick = () => {
console.debug(this.domRefs.myForm!.elements) // screenshot below
const {a, b, c} = this.domRefs.myForm!.elements
}
I don't want to use the : any
type annotation that does not emit this error.
Upvotes: 4
Views: 1226
Reputation: 55
As described by @oleg-valter-is-with-ukraine,
interface HTMLFormControlsCollection extends HTMLCollectionBase {
[item: string]: HTMLInputElement | RadioNodeList;
}
It worked for me I just changed the Element to HTMLInputElement
in the lib.dom.d.ts
file
Upvotes: -1
Reputation: 10365
This is a limitation of the standard DOM definitions library (and still is in 2021). Here is how the HTMLFormControlsCollection
is defined in it - notice the lack of a string index signature (this is exactly why the error happens):
interface HTMLFormControlsCollection extends HTMLCollectionBase {
/**
* Returns the item with ID or name name from the collection.
*
* If there are multiple matching items, then a RadioNodeList object containing all those elements is returned.
*/
namedItem(name: string): RadioNodeList | Element | null;
}
Its parent interface HTMLCollectionBase
also lacks a string index signature (despite having a number index signature):
interface HTMLCollectionBase {
/**
* Sets or retrieves the number of objects in a collection.
*/
readonly length: number;
/**
* Retrieves an object from various collections.
*/
item(index: number): Element | null;
[index: number]: Element;
}
However, HTMLFormControlsCollection
should have a string index signature by definition (see the standard):
element = collection[name]
radioNodeList = collection[name]
Returns the item with ID or name name from the collection.
So, with the help of some declaration merging, we can fix the omission:
interface HTMLFormControlsCollection extends HTMLCollectionBase {
[item: string]: Element | RadioNodeList;
}
Upvotes: 2