我正在编写一个打字稿定义,我的目录如下:
src
task.ts
typings
task.d.ts
如果我这样写打字:
declare namespace task {
export interface TaskInfo {
line: string;
}
}
它工作正常,但现在我想引用其他类型的输入,例如vscode
,如下所示:
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument; // now it cannot find the module vscode
}
}
现在我必须导入vscode
,但是当我将其更改为:
import * as vscode from "vscode"; // import here
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
我收到这样的错误:
error TS2503: Cannot find namespace 'task'
如果我将其更改为此:
declare namespace task {
import * as vscode from "vscode"; // import here
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
这次我得到这样的错误:
Import declarations in a namespace cannot reference a module.
那么,我应该怎么写我的打字?
答案 0 :(得分:2)
文件中一旦有import
或export
行,该文件即成为模块。这意味着该文件中定义的所有内容都仅作用于该文件。如果要从另一个文件中使用它,则需要将其导入。
当文件中没有任何import
或export
时,该文件中的变量(或类型声明)将位于全局范围内。
所以-
declare namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument; // now it cannot find the module vscode
}
}
声明一个名为task
的命名空间,该命名空间在全局范围内可用,并且可以从任何文件访问。 (这可能很糟糕!名称冲突等等)
一旦您添加import * as vscode from "vscode";
该文件是一个模块,现在task
需要导出,并从您要使用的任何文件中导入。像这样:
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';
...
这是选项1。(我认为更好)
我们还有另一个选择。由于在javascript世界中,模块仍将东西放在全局范围内并不少见,因此typescript确实允许这样做(但仅用于类型声明!您将无法在模块内实际在全局范围内创建值)< / p>
import * as vscode from "vscode"; // import here
declare global {
namespace task {
export interface TaskInfo {
line: string;
doc: vscode.TextDocument;
}
}
}
您将可以从任何其他文件访问task.TaskInfo
。