Ambient declaration with an imported type in TypeScript
Don't know if you're still looking for an answer, but this is the correct way to handle it and still be able to e.g. define generic modules, not just named namespaces: (original answer this is based on)
// myapp.d.ts
declare namespace MyApp {
import {SomeType} from 'module'
interface MyThing {
prop1: string
prop2: number
prop3: SomeType
}
}
Since TS 2.9 this is possible with import()
:
// myapp.d.ts
declare type SomeType = import('module').SomeType;
declare type SomeDefaultType = import('module-with-default-export').default;
declare namespace MyApp {
interface MyThing {
prop1: string;
prop2: number;
prop3: SomeType | SomeDefaultType;
}
}
Yes, there is a way. It has become easier in TypeScript 2.9 by using import() a type but it's also possible in earlier versions of TypeScript.
The following file is a script. Things declared in a script are added to the global scope. This is why you can use MyApp.MyThing
without importing it.
// myapp.d.ts
declare namespace MyApp {
interface MyThing {
prop1: string;
prop2: number;
}
}
Scripts are limited in that they cannot import anything; when you add an import
, the script becomes a module. I think it's weird to say the least, but it is what it is. What matters is that things defined in a module are scoped to that module, and are not added to the global scope.
However, modules can add declarations to the global scope too, by putting them inside global
:
// myapp.d.ts
import {SomeType} from 'module';
declare global {
namespace MyApp {
interface MyThing {
prop1: string;
prop2: number;
prop3: SomeType;
}
}
}
This file is a module, but it adds a declaration of MyApp.MyThing
to the global scope, so you can still use MyApp.MyThing
in other TypeScript code without importing it.
Note that using the .d.ts
extension has nothing to do with you being able to access the interface without importing it. Both of the above files could have been .ts
files and would still behave exactly the same.