【发布时间】:2017-05-30 14:23:35
【问题描述】:
如何将我的 Typescript 项目编译为 TS 编译,然后将其导入其他 TS 项目并使用类型定义?为了向后兼容,我也想将它们导出为纯 JS,以便其他不使用 TS 的人仍然可以使用该项目。
【问题讨论】:
标签: javascript typescript webpack typescript-typings
如何将我的 Typescript 项目编译为 TS 编译,然后将其导入其他 TS 项目并使用类型定义?为了向后兼容,我也想将它们导出为纯 JS,以便其他不使用 TS 的人仍然可以使用该项目。
【问题讨论】:
标签: javascript typescript webpack typescript-typings
您需要将项目发布为 npm 包。如果你愿意,你可以在 npm 上创建一个私有包(但你需要一个付费帐户),或者你可以公开发布它,或者你可以使用sinopia,它基本上是一个 npm 的本地实例。
这些选项中的任何一个都要求您拥有指定项目依赖项的最新 package.json 文件。
您将以编译的形式发布您的包。因此,如果您正确指定 tsconfig 和 package.json,您将导出 js 文件和 d.ts。文件和包将可以通过 typescript 或 vanilla javascript 使用。
【讨论】:
这就是我的做法:
// package.json
// The property name: @my-org/... means that the package is scoped -
// you can point a @scope at a specific NPM registry.
// See https://docs.npmjs.com/misc/scope
// We use myget.org to host our private packages.
{
"name": "@my-org/ng-lib",
"version": "1.0.8",
"main": "dist/index.js",
"scripts": {
"transpile": "tsc --outDir ./",
"clean": "rimraf ./services && rimraf ./*.js && rimraf ./*.d.ts"
},
"author": "*** <me@my-org.com>",
"license": "ISC",
"files": [
"**/*.js",
"**/*.d.ts"
],
"typings": "index.d.ts",
"dependencies": {
"@types/angular": "^1.5.20",
"angular": "^1.5.9"
},
"devDependencies": {
"rimraf": "^2.5.4"
}
}
编辑:
注意到 "typings": "index.d.ts" 行了吗?这描述了包的主要“类型”文件。因此,当您执行 import * as ngLib from '@my-org/ng-lib' 时,它将使用来自 node_modules/@my-org/ng-lib/index.d.ts 的类型intellisense,在编译后,webpack 会在 node_modules/@my-org/ng-lib/dist/index.js
找到主 js 文件因此,如果您手动创建了一个 index.d.ts 并且您要导出的只是接口,您可以将类型字段指向该 index.d.ts,因为接口没有实现,只需描述物体的形状。
但是,如果您有具有逻辑的对象(方法、getter/setter 等),它们很可能是类,您需要将其转换为 .js 和 .d.ts 文件。
示例:
./index.ts # Re-exports both my-class and my-interface
./my-class.ts # Implements my-interface.d.ts
./my-interface.d.ts
这个转译后的输出应该如下在一个“类型化”的 NPM 包中:
./index.d.ts
./index.js
./my-class.js
./my-class.d.ts
./my-interface.d.ts
而 package.json 将包含以下几行:
"main": "./index.js",
"typings": "./index.d.ts",
"files": [
"./index.d.ts",
"./index.js",
"./my-class.js",
"./my-class.d.ts",
"./my-interface.d.ts"
]
...在使用包时(一旦它被发布并安装在另一个项目中)可以通过以下方式完成:
import * as ngLib from '@my-org/ng-lib'
import { MyClass } from '@my-org/ng-lib'
import { MyInterface } from '@my-org/ng-lib'
import { MyClass } from '@my-org/ng-lib/my-class'
import { MyInterface } from '@my-org/ng-lib/my-interface'
结束编辑
tsconfig.json 中的 declaration 属性将发出 .d.ts 文件,描述您导出对象的“形状”。
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": false,
"emitDecoratorMetadata": true,
"declaration": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": false,
"baseUrl": "./src",
"listFiles": true,
"noImplicitUseStrict": false
},
"exclude": [
"node_modules"
]
}
如果它是一个复杂的包,我将有单独的模块并将它们聚合在 index.ts 中,如下所示:
// index.ts
export * from './module-one'
export * from './module-two'
export * from './module-three'
您还可以有子目录,每个子目录都有自己的索引。
这将创建 index.js 和 index.d.ts 文件,允许执行以下操作:
import * as ngLib from '@my-org/ng-lib'
import { ModuleOne } from '@my-org/ng-lib/module-one'
import { SubModuleOne } from '@my-org/ng-lib/submodules/submodule-one'
【讨论】:
.d.ts。我已经创建了我的接口。我只想将它们导出到一个文件中。我所有的接口文件都在一个目录./interfaces 中,我创建了一个index.d.ts 包括我想要公开的文件。那么我该如何导出呢?