是否可以在TypeScript中导出封装在名称空间/模块中的接口/类型?

时间:2019-03-15 05:28:01

标签: angular typescript typescript-typings

我对Typescript还是比较陌生,并且正在尝试从创建的私有ts回购中导入和重用接口,以便在node / ts服务器和Angular客户端之间共享类型/类/接口。这是通过在Angular package.json中将私有存储库作为依赖项来实现的。

名称空间在ts repo中声明,如下所示:

export namespace foo {
  export interface Bar {
   ...
  };
  export type Foo {
  ...
  };

在将foo导入到客户端import { foo } from 'repo/foo后,我可以访问函数和类(例如foo.fn()),但是我看不到或访问Bar接口或Foo类型。

这是因为接口和类型仅是ts,并且Angular客户端只能导入可使用javascript编译的东西吗?

包所有者想要在命名空间中声明所有内容,但我不想重新声明/重复类型和接口,因为这会否定共享ts包的大部分用途。

如果您可以建议其他方法,将不胜感激!

2 个答案:

答案 0 :(得分:0)

在仅用于编译步骤的Typescript接口中,用于检查引用变量的正确用法。 Typescript编译器不会在javascript中创建 interface type 的函数。
您应该使用界面和类型来定义变量和函数的类型:

import { foo } from 'repo/foo';

var item1: foo.Bar;
var func = (): foo.Foo => {
...
}

Typescript interfaces
Typescript namespaces

如果您使用编译为javascript lib'repo'的代码,则不能使用在typescript中声明的类型和接口,因为编译器不会在js中为接口创建任何东西。
但是您不能使用未编译的lib通过将这个作为模块导入(如果后端和客户端作为一个项目)。

答案 1 :(得分:0)

**已解决**

我通过反复试验自行解决了此问题。在我的用例(在单独的和独立的客户端/服务器TS仓库(NON-monorepo)中共享一个单独的TS仓库)中起作用的是,通过声明名称空间,就像我在原始问题中一样,但是问题是:

1)vscode intellisense无法在共享软件包的每个npm i上可靠地更新。有时确实如此。有时并非如此。如果无法识别共享仓库的名称空间/类型/枚举的更改,请始终关闭并重新打开整个vscode窗口(您在其中运行npm i进行导入)。您不必关闭所有窗口。只是没有更新。随着时间的流逝,您将确切地了解可以导入和不能导入的内容以及何时智能感知未正确更新。有时,导航到已编译的/ node_modules /中的名称空间将导致识别更改,但并非总是如此。

2)我试图在我自己的计算机上的package.json中本地链接到共享存储库。当您安装ts遥控器时,它会编译。您只能将ts编译的内容导入并使用到.d.ts后缀文件中。我发现更容易在共享存储库中进行更改,提交并推送到远程,然后在客户端/服务器存储库中运行npm i git+ssh://git@github.com/<user>/<repo>#<branch>。这样可以确保我始终具有与其他从远程安装共享软件包的开发人员相同的经验。

3)您必须同时使用export命名空间和该命名空间中的所有封装接口/类型/枚举,否则它将无法编译为.d.ts,并且您无法将这些更改导入到单独的目录中远程位置。

4)始终使用客户机/服务器提交(对于共享包所做的更改)提交package-lock.json,因为它会保留已为这些更改导入的确切共享包提交哈希。

我还为所有枚举和类型(enums.ts,每个枚举在名称空间中按字母顺序排序)创建了一个文件和名称空间。这比允许在任何地方声明它们都更加干净和容易共享,尤其是对于导入到客户端/服务器中而言:

import { enums, types } from 'shared_package';

const variable: types.ProductType = enums.PRODUCT.TYPE

尝试通过区分每个名称空间来防止名称空间与通用变量名称冲突。 ns_enums

祝你好运!