21

I am creating a textarea element in my TSX markup, and the TS typechecker in Vim complains 2540: Cannot assign to style because it is a read-only property. Having textarea.style be read-only is a bit weird, given that it can be written to ...

vim error How can I make the error message disappear? Should I cast the input variable in my code to something else?

romainl
  • 186,200
  • 21
  • 280
  • 313
oligofren
  • 20,744
  • 16
  • 93
  • 180
  • I did not know that this was even valid. I only ever assigned the properties within the style map. So here that could be done using e.g. `Object.assign(input.style, { whiteSpace: 'pre', position: 'absolute', left: '-9999px' })` – H.B. Oct 07 '20 at 12:16
  • @H.B. Sure, that is one way. Kind of common, though. Apparently using a string is not _recommended_ (according to MDN): https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style – oligofren Oct 08 '20 at 13:54

3 Answers3

24

I solved it by using:

input.setAttribute('style', 'white-space: pre; position: absolute; left: -9999px;');

Apparently "TypeScript does not have a style property on Element." as was mentioned in a related Stackoverflow answer.

gignu
  • 1,763
  • 1
  • 14
  • 24
3

alternatively you can use input.style.cssText

input.style.cssText = "white-space:pre; position:absolute; left:-9999px;";

  • This worked for me, whereas if I tried to cast to `HTMLDivElement` TypeScript still complained about `style` being read-only. – Ben Apr 25 '23 at 14:57
1

Apparently, I already had the answer ...

Saying the input variable is the specific type made it work.

const input: HTMLTextAreaElement = document.createElement('textarea')                                                                                                   
const currentTarget = e.currentTarget as HTMLDivElement    

This is probably because createElement can create all kinds of elements and Typescript has no way of knowing which, as it is based on the input string. So you need to say what it is returning.

oligofren
  • 20,744
  • 16
  • 93
  • 180
  • 1
    Actually, the TypeScript type declarations (here `lib.dom.d.ts`) have overloads, so `createElement` should already return the correct type. Where this is not quite possible is `querySelector`, which is not necessarily just a tag name. (So `document.querySelector('a')` gives you type `HTMLAnchorElement` but `document.querySelector('a[href]')` only gives you `Element`.) The problem here is `currentTarget`, which cannot be typed automatically. – H.B. Oct 07 '20 at 12:21
  • > The problem here is currentTarget, which cannot be typed automatically. Sure, it is a problem, but that has nothing to do with the error in question. The implicit type for `input` cannot have been correct, as specifying the type made the TS2540 error go away. If TS thought it was a `HTMLTextAreaElement ` already, specifying it would be a no-op. – oligofren Oct 08 '20 at 13:57
  • That is what i am saying, [it absolutely is a no-op](https://imgur.com/x7ysWgq). – H.B. Oct 08 '20 at 14:59
  • 1
    Also, assigning a string to `style` should always give you an error because the property is typed as read-only. So the only way you should be able to not get the error is if you somehow lose the type information, e.g. assert `any`. – H.B. Oct 08 '20 at 15:06
  • @H.B. The TS compiler never complained, but the linter somehow did, and to it, adding the type was not a no-op, ... No idea what the difference is caused by. – oligofren Oct 09 '20 at 13:12