Repository: tradingview/lightweight-charts
Pull request #172 (2019-08-15 09:13:58)

Make IDE and tools happy with TypeScript
Currently IDE (like VSCode) uses nearest tsconfig to navigate/error detection (see https://github.com/microsoft/vscode/issues/12463).

This commit switch composite tsconfig with non-composite one (renames, actually), and now IDE should works fine and does navigation properly.
The compilation (`tsc`/`tsc-all`/etc scripts) **still uses composite project** (for instance for speed and checking cyclic deps).

Also, the PR introduced new `_global-types` global types to place global types there
(like enum for mouse button or `TimerId` to prevent conflicts with nodejs typing while compile with non-composite tsconfig).

`TimerId` should be used to store `setTimeout`/`setInterval` result to prevent errors (it's just `ReturnType<typeof setTimeout>`).


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 685bacaaf..c99c1645e 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -81,6 +81,11 @@ jobs:
     steps:
       - checkout-with-deps
       - run: npm run tsc-all
+
+      # make sure that the project is compiled with non-composite project
+      # it doesn't output anything, but is used by IDE or tools
+      - run: ./node_modules/.bin/tsc -p tsconfig.json
+
       - run: npm run build:prod
       - persist_to_workspace:
           root: ./
diff --git a/.mocharc.js b/.mocharc.js
index 09633ffcd..1cf28d893 100644
--- a/.mocharc.js
+++ b/.mocharc.js
@@ -3,7 +3,7 @@
 const path = require('path');
 
 // override tsconfig for tests
-process.env.TS_NODE_PROJECT = path.resolve(__dirname, './tests/unittests/tsconfig.json');
+process.env.TS_NODE_PROJECT = path.resolve(__dirname, './tests/unittests/tsconfig.composite.json');
 
 const config = {
 	require: [
diff --git a/dts-config.js b/dts-config.js
index 3a513ea66..b245de788 100644
--- a/dts-config.js
+++ b/dts-config.js
@@ -3,7 +3,7 @@
 /** @type import('dts-bundle-generator/config-schema').BundlerConfig */
 const config = {
 	compilationOptions: {
-		preferredConfigPath: './tsconfig.all-non-composite.json',
+		preferredConfigPath: './tsconfig.json',
 	},
 	entries: [
 		{
diff --git a/package.json b/package.json
index 4a0d983e1..07bfa6b05 100644
--- a/package.json
+++ b/package.json
@@ -66,13 +66,13 @@
     "install-hooks": "node scripts/githooks/install.js",
     "clean": "rimraf lib/ dist/",
     "bundle-dts": "tsc --noEmit --allowJs dts-config.js && dts-bundle-generator --config dts-config.js",
-    "tsc": "tsc -b src",
-    "tsc-watch": "tsc -b --watch --preserveWatchOutput",
-    "tsc-all": "tsc -b .",
-    "tsc-all-watch": "tsc -b . --watch --preserveWatchOutput",
+    "tsc": "tsc -b src/tsconfig.composite.json",
+    "tsc-watch": "npm run tsc -- --watch --preserveWatchOutput",
+    "tsc-all": "tsc -b tsconfig.composite.json",
+    "tsc-all-watch": "npm run tsc-all -- --watch --preserveWatchOutput",
     "lint": "npm-run-all -p lint:**",
     "lint:eslint": "eslint --format=unix --ext .js ./",
-    "lint:tslint": "tslint --config tslint.json --project tsconfig.all-non-composite.json",
+    "lint:tslint": "tslint --config tslint.json --project tsconfig.json",
     "lint:md": "./node_modules/.bin/markdownlint -i \"**/node_modules/**\" \"**/*.md\"",
     "check-markdown-links": "node scripts/check-markdown-links.js",
     "rollup": "rollup -c rollup.config.js",
diff --git a/src/api/tsconfig.json b/src/api/tsconfig.composite.json
similarity index 63%
rename from src/api/tsconfig.json
rename to src/api/tsconfig.composite.json
index 466acc8c7..a1679c550 100644
--- a/src/api/tsconfig.json
+++ b/src/api/tsconfig.composite.json
@@ -4,8 +4,8 @@
 		"composite": true
 	},
 	"references": [
-		{ "path": "../formatters" },
-		{ "path": "../gui" },
+		{ "path": "../formatters/tsconfig.composite.json" },
+		{ "path": "../gui/tsconfig.composite.json" },
 		{ "path": "../tsconfig.model.json" }
 	],
 	"include": [
diff --git a/src/formatters/tsconfig.json b/src/formatters/tsconfig.composite.json
similarity index 73%
rename from src/formatters/tsconfig.json
rename to src/formatters/tsconfig.composite.json
index 07b357434..987b8f837 100644
--- a/src/formatters/tsconfig.json
+++ b/src/formatters/tsconfig.composite.json
@@ -4,7 +4,7 @@
 		"composite": true
 	},
 	"references": [
-		{ "path": "../helpers" }
+		{ "path": "../helpers/tsconfig.composite.json" }
 	],
 	"include": [
 		"./**/*.ts"
diff --git a/src/gui/mouse-event-handler.ts b/src/gui/mouse-event-handler.ts
index 124c2a2c6..4521e4129 100644
--- a/src/gui/mouse-event-handler.ts
+++ b/src/gui/mouse-event-handler.ts
@@ -57,10 +57,6 @@ const enum Delay {
 	LongTap = 240,
 }
 
-const enum MouseEventButton {
-	Left = 0,
-}
-
 export interface MouseEventHandlerOptions {
 	treatVertTouchDragAsPageScroll: boolean;
 	treatHorzTouchDragAsPageScroll: boolean;
@@ -74,8 +70,8 @@ export class MouseEventHandler implements IDestroyable {
 	private readonly _options: MouseEventHandlerOptions;
 
 	private _clickCount: number = 0;
-	private _clickTimeoutId: number | null = null;
-	private _longTapTimeoutId: number | null = null;
+	private _clickTimeoutId: TimerId | null = null;
+	private _longTapTimeoutId: TimerId | null = null;
 	private _longTapActive: boolean = false;
 	private _mouseMoveStartPosition: Position | null = null;
 	private _moveExceededManhattanDistance: boolean = false;
diff --git a/src/gui/price-axis-widget.ts b/src/gui/price-axis-widget.ts
index d153d8e12..d87aaeab6 100644
--- a/src/gui/price-axis-widget.ts
+++ b/src/gui/price-axis-widget.ts
@@ -44,7 +44,7 @@ export class PriceAxisWidget implements IDestroyable {
 	private readonly _topCanvas: HTMLCanvasElement;
 	private readonly _topCtx: CanvasRenderingContext2D;
 
-	private _updateTimeout: number | null = null;
+	private _updateTimeout: TimerId | null = null;
 	private _mouseEventHandler: MouseEventHandler;
 	private _mousedown: boolean = false;
 
diff --git a/src/gui/tsconfig.json b/src/gui/tsconfig.composite.json
similarity index 100%
rename from src/gui/tsconfig.json
rename to src/gui/tsconfig.composite.json
diff --git a/src/helpers/tsconfig.json b/src/helpers/tsconfig.composite.json
similarity index 100%
rename from src/helpers/tsconfig.json
rename to src/helpers/tsconfig.composite.json
diff --git a/src/tsconfig.json b/src/tsconfig.composite.json
similarity index 50%
rename from src/tsconfig.json
rename to src/tsconfig.composite.json
index e58fdae72..cd2bca798 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.composite.json
@@ -4,10 +4,10 @@
 		"composite": true
 	},
 	"references": [
-		{ "path": "./api" },
-		{ "path": "./formatters" },
-		{ "path": "./gui" },
-		{ "path": "./helpers" },
+		{ "path": "./api/tsconfig.composite.json" },
+		{ "path": "./formatters/tsconfig.composite.json" },
+		{ "path": "./gui/tsconfig.composite.json" },
+		{ "path": "./helpers/tsconfig.composite.json" },
 		{ "path": "./tsconfig.model.json" }
 	],
 	"include": [
diff --git a/src/tsconfig.model.json b/src/tsconfig.model.json
index e686520e5..5008f9074 100644
--- a/src/tsconfig.model.json
+++ b/src/tsconfig.model.json
@@ -4,8 +4,8 @@
 		"composite": true
 	},
 	"references": [
-		{ "path": "./formatters" },
-		{ "path": "./helpers" }
+		{ "path": "./formatters/tsconfig.composite.json" },
+		{ "path": "./helpers/tsconfig.composite.json" }
 	],
 	"include": [
 		"./model/**/*.ts",
diff --git a/src/typings/_build-time-constants/index.d.ts b/src/typings/_build-time-constants/index.d.ts
index 99bf7f8c4..62ae9ed98 100644
--- a/src/typings/_build-time-constants/index.d.ts
+++ b/src/typings/_build-time-constants/index.d.ts
@@ -2,9 +2,15 @@
 // which will be replaced (injected) by rollup while bundling
 // see rollup.config.js for the reference
 
-declare const process: {
-	env: {
+declare namespace NodeJS {
+	interface ProcessEnv {
 		NODE_ENV: 'development' | 'production';
 		BUILD_VERSION: string;
-	};
-};
+	}
+
+	interface Process {
+		env: ProcessEnv;
+	}
+}
+
+declare var process: NodeJS.Process;
diff --git a/src/typings/_global-types/index.d.ts b/src/typings/_global-types/index.d.ts
new file mode 100644
index 000000000..d8b272a8d
--- /dev/null
+++ b/src/typings/_global-types/index.d.ts
@@ -0,0 +1,18 @@
+/**
+ * This type should be used when you need to save result of the setTimeout/setInterval functions.
+ * It makes the compilation with non-composite project happy.
+ */
+type TimerId = ReturnType<typeof setTimeout>;
+
+/**
+ * The type declares compile-time constants for mouse buttons.
+ * e.button values for MouseEvents.
+ * It's NOT e.buttons (with s)!
+ */
+declare const enum MouseEventButton {
+	Left = 0,
+	Middle = 1,
+	Right = 2,
+	Fourth = 3,
+	Fifth = 4,
+}
diff --git a/tsconfig.all-non-composite.json b/tsconfig.all-non-composite.json
deleted file mode 100644
index 34d551ceb..000000000
--- a/tsconfig.all-non-composite.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-	"extends": "./tsconfig.base.json",
-	"include": [
-		"src/**/*.ts",
-		"tests/**/*.ts"
-	]
-}
diff --git a/tsconfig.base.json b/tsconfig.base.json
index d52a67f65..2c0739c1a 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -29,6 +29,8 @@
 			"./src/typings",
 			"node_modules/@types"
 		],
-		"types": []
+		"types": [
+			"_global-types"
+		]
 	}
 }
diff --git a/tsconfig.composite.json b/tsconfig.composite.json
new file mode 100644
index 000000000..e1efa04ee
--- /dev/null
+++ b/tsconfig.composite.json
@@ -0,0 +1,11 @@
+{
+	"extends": "./tsconfig.base.json",
+	"compilerOptions": {
+		"composite": true
+	},
+	"references": [
+		{ "path": "./src/tsconfig.composite.json" },
+		{ "path": "./tests/unittests/tsconfig.composite.json" }
+	],
+	"include": []
+}
diff --git a/tsconfig.json b/tsconfig.json
index e71267f6a..caea5c495 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,10 @@
 {
 	"extends": "./tsconfig.base.json",
 	"compilerOptions": {
-		"composite": true
+		"noEmit": true,
 	},
-	"references": [
-		{ "path": "./src" },
-		{ "path": "./tests/unittests" }
-	],
-	"include": []
+	"include": [
+		"src/**/*.ts",
+		"tests/**/*.ts"
+	]
 }


Test patch:
diff --git a/tests/unittests/tsconfig.json b/tests/unittests/tsconfig.composite.json
similarity index 76%
rename from tests/unittests/tsconfig.json
rename to tests/unittests/tsconfig.composite.json
index 307c9ef50..eafb9d364 100644
--- a/tests/unittests/tsconfig.json
+++ b/tests/unittests/tsconfig.composite.json
@@ -5,7 +5,7 @@
 		"module": "commonjs"
 	},
 	"references": [
-		{ "path": "../../src" }
+		{ "path": "../../src/tsconfig.composite.json" }
 	],
 	"include": [
 		"./**/*.ts"