48

I would like to use the SVG use element in a .tsx file:

<mask id="mask1">
    <use ... />
</mask>

I'm transpiling this to React calls directly. However, I keep receiving the following error:

Property 'use' does not exist on type 'JSX.IntrinsicElements'.

I believe this element is missing from the standard lib definitions. How can I declare this type for the TypeScript compiler to see, similar to how I can declare a class or variable? The usual declare var and declare class statements have no effect.

If that's not possible, how can I make the TypeScript compiler ignore this error?

John Weisz
  • 30,137
  • 13
  • 89
  • 132

8 Answers8

140

If you want to ignore an error inline, use this weird syntax:

{/* 
// @ts-ignore */}
<Foo id="fooDoesNotHaveIdType" /> 

Taken from https://github.com/Microsoft/TypeScript/issues/27552

captDaylight
  • 2,224
  • 4
  • 31
  • 42
Mikey
  • 2,675
  • 4
  • 18
  • 24
64

I tried @Mikey's solution it did not work, but the following works for me:

    <Foo
      /*
      // @ts-ignore */
      id="foo does not have IdType"
      baz="foo Have bazType"
    /> 

In the above I am ignoring type error in property id

apollo
  • 2,467
  • 1
  • 20
  • 29
  • I was looking for attribute ignoring in `jsx`. It works for me too. Thank you. – Ibrahim Sakaci Dec 05 '21 at 20:18
  • In my opinion this might be a bit risky because `baz` wouldn't get proper type-checking anymore. See: [https://github.com/microsoft/TypeScript/issues/49972](https://github.com/microsoft/TypeScript/issues/49972) - don't have a solution for this yet. What do you think? – Nico W. Jul 20 '22 at 17:04
  • Just `/* @ts-ignore */` or `// @ts-ignore` works – Spikatrix Mar 02 '23 at 07:29
19

A use inside mask no longer throws a type error but if it still did today you could:

<mask id="mask1">
    {/* @ts-ignore */} 
    <use ... />
</mask>
vhs
  • 9,316
  • 3
  • 66
  • 70
10

You can use @ts-ignore:

{/* @ts-ignore */} 
<mask id="mask1">
  <use ... />
</mask>

It also works if you use inline conditions:

{
  /* @ts-ignore */ myCondition && (
    <mask id="mask1">
      <use ... />
    </mask>
  )
}
Giovanni Benussi
  • 3,102
  • 2
  • 28
  • 30
7

As of 3/20/22, the best solution to me seems to be /* @ts-expect-error */:

<ComponentWithTroublesomeProp
  okayProp={a}
  anotherOkayProp={b}
  /* @ts-expect-error */
  problematicProp={cGotTroubles}
  yetAnotherOkayProp={d}
/>

Judging from the relevant GitHub Issue, what the accepted answer proposes is now out of date.

You could also try // @ts-ignore, but if you have @typescript-eslint set up, you probably have the @typescript-eslint/ban-ts-comment rule enabled, meaning you'd have to use do something like this, using two lines instead of one:

<ComponentWithTroublesomeProp
  okayProp={a}
  anotherOkayProp={b}
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  problematicProp={cGotTroubles}
  yetAnotherOkayProp={d}
/>
Adam Zerner
  • 17,797
  • 15
  • 90
  • 156
  • This is perfect for my situation, thank you. This has the added bonus that eslint prompts to also add a description/reason for adding the expect-error, so for example ` /* @ts-expect-error a descriptive reason for ignoring here */ ` – cjwiseman11 Jan 25 '23 at 14:19
4

I'm transpiling this to React calls directly

One workaround is using React.createElement directly:

<mask id="mask1">
    {React.createElement("use", { ... })}
</mask>

This isn't pretty, but it gets the job done, and the compiled output is essentially the same.

John Weisz
  • 30,137
  • 13
  • 89
  • 132
3

Just to add to the solution provided by Giovanni Benussi

The official documentation states that -

A // @ts-ignore comment suppresses all errors that originate on the following line. It is recommended practice to have the remainder of the comment following @ts-ignore explain which error is being suppressed.

Adding the line {/* @ts-ignore */} before the JSX component will ignore error in the following line. Example -

   {/* @ts-ignore */}
    <mask id="mask1">
      <use ... />
    </mask>

If you have component props defined on multiple lines and you have an issue on one of these props, then you can do the following (observe the difference) -

<mask id="mask1">
   <use 
      prop_one="Lets say this is ok"
      /* @ts-ignore */
      prop_two="There is a validation error"
   />
</mask>
Fahim Hossain
  • 1,671
  • 13
  • 16
  • How are you getting this working without making the whole set of props "ignored"? I made some testing around and wasn't able to ignore only "one line" (so one prop). It always ignores all props and leave them "unchecked". See: [https://github.com/microsoft/TypeScript/issues/49972](https://github.com/microsoft/TypeScript/issues/49972) What do you think? – Nico W. Jul 20 '22 at 16:24
2

use and other SVG elements have been added to TS's JSX definitions at the time of this writing, so the accepted answer's workaround is no longer necessary--but for anyone brought here because they need to get a custom element (web component, different UI framework, etc) working in a TSX file, follow these steps:

  1. Create a .d.ts file. I like to put mine in the same folder as tsconfig.json
  2. Add your definitions to this file, like:

    declare module JSX { interface IntrinsicElements { 'some-custom-element': any; } }

The .d.ts file is automatically found by TS and then it stops complaining. I had to restart my TS server for it to pick up the changes.

ccnokes
  • 6,885
  • 5
  • 47
  • 54