2

I've read this answer about how to extend built-in types, but it only tells half the story. How do we tell TypeScript where to find our global definitions?

I've created a file,

src/cssom.d.ts

interface HTMLElement {
    computedStyleMap(): any
}

And then tried including it with include (not sure if this is the best option or not):

tsconfig.json

{
    "compilerOptions": {
        ...
    },
    "files": [
        "src/index"
    ],
    "include": [
        "src/**/*.d.ts"
    ],
    "exclude": [
        "node_modules"
    ]
}

But my VS Code still complains:

enter image description here

Even though it compiles without error or warnings via awesome-typescript-loader.

So what do I have to do to get the language service to behave? What's the best way to configure tsconfig to read all my *.d.ts files?


Adding

///<reference path="cssom.d.ts"/>

To the top of the file satisfies both the compiler and the language service, but I really don't want to add these <reference>s everywhere since I'm extending a built-in/global type.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • Open root of your ReactApp. It should have properly configured tsconfig.json Otherwise follow this guide https://www.typescriptlang.org/docs/handbook/react-&-webpack.html – zoonman Aug 23 '18 at 21:48
  • @zoonman The webpack part is working fine. It's the TS language service that doesn't know what's up – mpen Aug 23 '18 at 22:11

2 Answers2

3

I think you want the "typeRoots" tsconfig compiler option. I think you can solve this by including your file in the typeRoots array

"typeRoots": [
  "src/cssom.d.ts"
]

Or you can simply include a path to a folder in the typeRoots array to include all types in that folder.

Update:

Incidentally, I only know this because the typescript-starter project automatically configures a default typeRoots folder for you and explains how to use it. Very helpful.

Update 2:

I suppose it's worth noting that the typescript documentation specifically says the typeRoots option should include a list of folder paths, so it's possible pointing to a specific *.d.ts file wouldn't work.

Update 3:

As @mpen pointed out, including your own typeRoots will overwrite the default node_modules/@types typeRoot. So you'll want to specifically include that typeRoot as well:

i.e. "typeRoots": ["node_modules/@types", "src/types"]

John
  • 9,249
  • 5
  • 44
  • 76
  • If I use `typeRoots` it'll stop checking `node_modules/@types` as far as I'm aware. I want to retain the defaults too – mpen Aug 23 '18 at 21:46
  • @mpen Good point, in my project I have `"typeRoots": ["node_modules/@types", "src/types"]` – John Aug 23 '18 at 21:49
  • 2
    Tried it. Now both the language service *and* the compiler are complaining. I *think* typeRoots expects *modules* in there judging by this typescript-starter example. I don't have a module, I'm extending a built-in type. – mpen Aug 23 '18 at 21:54
2

I think the tsx file shown in the screenshot is not part of the project defined by your tsconfig.json because it isn't referenced by either the files or the files matching the includes. Your "files" should probably be changed to ["src/index.tsx"]; I tested and the extension does make a difference.

Matt McCutchen
  • 28,856
  • 2
  • 68
  • 75
  • Oh my.... I think you're right! I just assumed I was allowed to leave off the extension because it was compiling. But I guess that's because of my webpack config, not my tsconfig. That explain it! Thank you! – mpen Aug 23 '18 at 22:17