Reputation: 9943
I am writing a typescript definition, my directory is like this:
src
task.ts
typings
task.d.ts
if I write typing like this:
declare namespace task {
export interface TaskInfo {
line: string;
}
}
it works fine, but now I want to refer typing in other typings, for example vscode
, like this:
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument; // now it cannot find the module vscode
}
}
now I have to import vscode
, but when I change it to:
import * as vscode from "vscode"; // import here
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
I get error like this:
error TS2503: Cannot find namespace 'task'
if I change it to this:
declare namespace task {
import * as vscode from "vscode"; // import here
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
this time I get error like this:
Import declarations in a namespace cannot reference a module.
So, how should I write my typings?
Upvotes: 0
Views: 182
Reputation: 1717
Once you have an import
or export
line in your file, that file becomes a module. This means that everything defined inside that file is scoped only to that file. If you want to use it from another file, you'll need to import it.
When your file doesn't have any import
or export
, variables (or type declarations) in that file sit at the global scope.
so this -
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument; // now it cannot find the module vscode
}
}
declares a namespace called task
that is available at the global scope, and accessible from any file. (Which can be bad! name collisions and all)
once you add import * as vscode from "vscode";
that file is a module, and now task
needs to be exported, and imported from any file you want to use. Something like this:
import * as vscode from "vscode"; // import here
export declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
/** in another file **/
import {task} from '../typings/task.d.ts';
...
This is option 1. (Which I think is better)
We have another option. Since in the javascript world it's not uncommon for modules to still put stuff on the global scope, typescript does allow this (but only for type declarations! you won't be able to actually create values on the global scope from within a module)
import * as vscode from "vscode"; // import here
declare global {
namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
}
you will be able to access task.TaskInfo
from any other file.
Upvotes: 2