I've been working with Typescipt for a few months, and this aspect has been annoying me over the course of several projects already. Suppose I have the following project structure:
project
+- app
| +- component1
| | +- component1.ts
| +- component2
| | +- component2.ts
| +- utils
| +- utils.ts
+- tsconfig.json
Now, suppose that utils.ts file contains a lot of helper classes (e.g. data structures) and maybe even global functions, and almost every other file in project uses at least some part of it. How would you use it with a minimum amount of boilerplate code?
Using import statement
// utils.ts
export function foo() { return 1; }
// component1.ts
import { foo, bar, baz, ...(a long list here) } from '../utils/utils'
let x = foo(); // looks fine
Pros: imported members are simple to use
Cons: necessity to maintain long import list in almost every other file
Another option is to import everything at once:
// component1.ts
import * as utils from '../utils/utils' // I have to remember to put this line on top of every other file, but it's better than the option above
let x = utils.foo(); // unavoidable prefixes all over the code
Pros: import statement is generic and can be copypasted to every file only changing the relative path (although I'd be happier if there would be a way to do so implicitly project-wide)
Cons: namespace prefixes for simple helper functions all over the code. For some reason Typescript doesn't allow to use import *
without explicit namespace.
Using triple-slash directive
// utils.ts
function foo() { return 1; } // no export keyword
// component1.ts
/// <reference path="../utils/utils.ts" />
let x = foo();
This looks much better even though I still have to specify a reference with relative path on top of every file. However, it breaks completely for me when I try to bundle my app with webpack - utils.js just doesn't get bundled along with the rest of the app (I guess this is a topic for another SO question).
What I would really like is the ability to use my code in utils.ts like I use global library classes - Map
, Set
, HTMLElement
, Promise
, etc., without any imports or prefixes, is there any way to achieve this?
P.S. Notice that I've long abandoned the good programming principle of actually splitting my utils.ts into multiple files (one per class/global function), as it would greatly exacerbate the problem above. I'm actually considering using a single file for the whole project already.