1

In my Angular app, I'm able to access Angular types by installing the package @types/angular. Then in my TS files, I'm able to do things like timeout: ng.ITimeoutService without having to import anything into my file. I can then run tsc and everything compiles just fine. VSCode also does not complain that it can't find ng.ITimeoutService.

However when I try to emulate this behavior with my own custom types, it doesn't work without me having to explicitly import the module in my file. Here's what I'm doing:

  1. Create file vendor/@types/custom/index.d.ts with contents:

    export declare class MyClass {...}

  2. In my tsconfig.json, I add this path to typeRoots:

    "typeRoots": ["./vendor/@types/custom"]

Now in my app file ./app/view.ts, I try to do this:

public myObject: MyClass

However VSCode, as well as tsc, complain:

Cannot find name 'MyClass'

I've even tried using references:

/// <reference path="../vendor/@types/custom/index.d.ts" />

But this gives the same result.

How do I access a type without importing its file, similar to how I'm able to access types in node_modules/@types without having to import them?

1 Answer 1

1

You might want to look at global definitions. I'm pretty sure that's how libraries like angular do ng.ITimeoutService. However you might need to have your own namespace like below.

/*~ If your library has properties exposed on a global variable,
 *~ place them here.
 *~ You should also place types (interfaces and type alias) here.
 */
declare namespace myLib {
  //~ We can write 'myLib.timeout = 50;'
  let timeout: number;
}

Edit

It seems that you can add a global class within a types.d.ts file. I'm using typescript 3.8.3 in VSCode.

Here's my types.d.ts

// This is accesible anywhere now
declare class Aaaaa {
  myFunction();
}

Here's my tsconfig.json

{
  "compilerOptions": {
    "outDir": "dist",
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es5",
    "lib": ["es6", "es2016", "dom"],
    "baseUrl": "src",
    "preserveConstEnums": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "typeRoots": ["node_modules/@types", "src/types.d.ts"]
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

Warning: Global types are not a good idea (should be a last resort option). Also the global class cannot have any initializers on it, so the implementation has to be loaded globally somewhere else (usually via script tags in the browser).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this gets me closer. But how if my definitions are generated automatically by tsc through tsconfig.json, how can I have automatically wrap the definitions in a namespace?
Also I appear to be able to access built-in types like Event, File, etc, without having to import them. These don't appear to have to do with namespaces. How are these picked up on by the compiler?
This still doesn't work for me. Cannot find name X if I don't import the module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.