我使用 swagger-codegen使用 -l typescript-angular
选项生成 REST 消费者服务库。生成的代码如下所示 (DefaultApi.ts
):
namespace API.Client {
'use strict';
export class DefaultApi {
protected basePath = 'http://localhost:7331/v1';
public defaultHeaders : any = {};
static $inject: string[] = ['$http', '$httpParamSerializer', 'basePath'];
constructor(protected $http: ng.IHttpService, protected $httpParamSerializer?: (d: any) => any, basePath?: string) {
if (basePath !== undefined) {
this.basePath = basePath;
}
}
private extendObj<T1,T2>(objA: T1, objB: T2) {
for(let key in objB){
if(objB.hasOwnProperty(key)){
objA[key] = objB[key];
}
}
return <T1&T2>objA;
}
/**
* Delete a person.
* Deletes a specified individual and all of that person's connections.
* @param id The id of the person to delete
*/
public deletePersonById (id: number, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> {/*...*/}
/* etc... */
}
}
如您所见,有些具体类需要使用,但在命名空间内声明,即不可导入
。尽管缺少 import
,但当我引用 API.Client.DefaultApi
时,我的编辑器 (VSCode) 没有提示,因为它将定义作为声明的命名空间的一部分认为。但在运行时,浏览器会提示 API
未定义。
我正在使用 webpack 来打包我的代码。我在 SO 上看到了一些其他问题,这些问题有点像这个问题,但没有找到那里的答案。
编辑:
根据要求,这是我的 ts 和 webpack 配置文件:
webpack 配置文件:
const webpack = require('webpack');
const conf = require('./gulp.conf');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
module.exports = {
module: {
preLoaders: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'tslint'
}
],
loaders: [
{
test: /.json$/,
loaders: [
'json'
]
},
{
test: /\.(css|less)$/,
loaders: [
'style',
'css',
'less',
'postcss'
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
loaders: [
'ng-annotate',
'ts'
]
},
{
test: /.html$/,
loaders: [
'html'
]
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
template: conf.path.src('index.html')
})
],
postcss: () => [autoprefixer],
debug: true,
devtool: 'source-map',
output: {
path: path.join(process.cwd(), conf.paths.tmp),
filename: 'index.js'
},
resolve: {
modules: [
path.resolve(__dirname, '../src/app'),
path.resolve(__dirname, '../node_modules')
],
extensions: [
'',
'.webpack.js',
'.web.js',
'.js',
'.ts'
]
},
entry: `./${conf.path.src('index')}`,
ts: {
configFileName: '../tsconfig.json'
},
tslint: {
configuration: require('../tslint.json')
}
};
tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src/app",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"module": "commonjs"
},
"compileOnSave": false,
"include": [
"src/**/*.ts"
],
"exclude": [
"!typings/**",
"!node_modules/**"
]
}
最佳答案
您有两种选择来解决这个问题,一种是简单的,另一种是复杂的:
- 更改生成的 ts 文件。
在生成的代码末尾添加如下代码:
export = API.Client;
现在,您可以毫无问题地在您的模块中使用import
,例如:
import {DefaultApi} from './generated-code';
- 但如果更改生成的文件不是一个选项,请诉诸 Salsa compiler !
想法:
使用不同的 tsconfig 拆分模块化代码而不是模块化代码。将模块化代码和非模块化代码与 Salsa、webpack 解析别名和 javascript 支持混合。
教程:
TL;DR Here a GitHub repository applying this solution.
- 新建tsconfig.generate.json to generated code handle,只生成代码,eg:
{
"compilerOptions": {
"outFile": "module-generated-code.js"
},
"files": ["generated-code.ts"]
}
- 在您的初始 tsconfig.json 中,您必须排除生成的 ts 文件。这将确保没有不必要的代码,例如:
{
"compilerOptions": {
},
"exclude": ["generated-code.ts"]
}
- 现在,王牌已成定局!您将添加一个
api.js
文件并在您的tsconfig.generate.json
中引用它。是的,它是一个js文件,Salsa就是在这里起作用的。为此,您必须在 tsconfig 中启用allowJs
功能
{
"compilerOptions": {
"outFile": "module-generate-code.js", "allowJs": true
},
"files": ["generated-code.ts", "api.js"]
}
这些文件基本上是通过 commonjs 导出您生成的代码而无需触摸它。
/// <reference path="./namespacing-code.ts" />
// typescript compiler don't warning this because is Salsa!
module.exports = API.Client;
现在,记下 tsconfig.generate.json
和您的 outFile
属性。如果您测试编译器 (tsc -p tsconfig.generate.json
),您会看到所有生成的文件都连接在 module-generate-code.js
中,最后一行必须是这样的:
module.exports = API.Client;
快完成了!
现在,您可以通过import
在您自己的代码中使用module-generate-code.js
!但是js文件没有最好的定义,那么你在webpack.config和tsconfig.json中配置一个resolve.alias
{ //webpack.config
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.js'],
alias:{ 'api':'./module-generated-code.js'
}
}
{ //tsconfig.json
"compilerOptions": {
"allowJs": true, //remember of enabling Salsa here too
"baseUrl": ".",
"paths": {
"api":["api.js"] //it is just get type definitions from generated files
}
},
现在您可以使用您生成的代码而无需触摸它:import api from 'api';
有任何疑问,这里是GitHub repo 使用这种方法。 希望对您有所帮助
关于typescript - 编译时正常,在带有 webpack 的 typescript 中使用命名空间中的类时出现运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41277018/