I have the following Angular multi-project file structure:
-AngularMultiProject
-projects
-mobile-app
-shared-lib
-web-app
-ViewModels
-Common
-myviewmodel1.d.ts
-myviewmodel2.d.ts
The shared-lib project and the web-app project are referencing viewmodels from the application root folder. I can build the web-app project, but not the shared-lib project. I get the following error:
EROR: ...component.ts:12:27 - error TS2503: Cannot find namespace 'Common'.
The typescript configuration for both projects is the same:
AngularMultiProject/tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"module": "esnext",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
//"downlevelIteration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2017",
"dom",
"es2019"
],
"paths": {
"shared": [
"dist/shared/shared",
"dist/shared"
]
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true
}
}
shared-lib/tsconfig.lib.json and web-app/tsconfig.lib.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"types": []
},
"include": [
"src/**/*.d.ts",
"../../ViewModels/**/*.d.ts"
]
}
After long trial and error I figured it out:
You have to put a .ts - file containing all the module / interface definitions into each angular project folder and reference it from at least one module file of your library / project.
The .ts file has to have the following structure:
declare module Common {
export interface MyAVM {
id: number;
name:string;
}
export interface MyBVM {
...
}
}
declare module CommonB {
export interface MyCVM {
id: number;
name:string;
}
export interface MyDVM {
...
}
}
You have to reference this file from at least one module file like this:
/// <reference path="../viewmodels.ts" />
We are using an ASP.Net Core WebApplication with the AspNetCore.SpaServices template. We are creating typescript definition files with the TypeScript Definition Generator extension for visual studio. We generate ViewModels to the ViewModels folder in the webapp root.
I created a grunt script to pull all the generated d.ts files and create the viewmodels.ts into all angular projectfoldes:
grunt.registerMultiTask("generateModuleFiles", "Create reference ts for viewmodels", function () {
var paths = grunt.file.expand(this.data.paths),
moduleName = '',
moduleFileContent = '',
completeModuleContent = '';
paths.forEach(function (path) {
var pathParts = path.split('/');
if (moduleName !== pathParts[pathParts.length - 2]) {
if (moduleName.length > 0) {
moduleFileContent += "\n}";
grunt.log.write(moduleName + "\n");
moduleFileContent = moduleFileContent.replace(moduleName + '.', '');
completeModuleContent += moduleFileContent;
}
moduleName = pathParts[pathParts.length - 2];
moduleFileContent = 'declare module ' + moduleName + ' {\n';
}
var fileContent = grunt.file.read(path)
moduleFileContent += "export " + fileContent + "\n";
});
if (moduleName.length > 0) {
moduleFileContent += "\n}";
moduleFileContent = moduleFileContent.replace(moduleName + '.', '');
grunt.log.write(moduleName + "\n");
completeModuleContent += moduleFileContent;
}
grunt.file.write('ClientApps/projects/shared/src/viewmodels.ts', completeModuleContent);
grunt.file.write('ClientApps/projects/WebApp/src/viewmodels.ts', completeModuleContent);
});
grunt.initConfig({
watch: {
viewmodels: {
files: [
'./ViewModels/**/*.d.ts'
],
tasks: [
'generateModuleFIles:all'
]
}
},
generateModuleFiles: {
all: {
paths: ["ViewModels/**/*.d.ts"]
}
}
});
}