Reputation: 1271
I'm using typescript 2.3.4, and I want to prevent @types/knockout exposing its global variable 'ko'. So I have put types:[] in the tsconfig.json and I explicitly want to import ko (like in second.ts). The problem is that the import I do in second.ts is making available @types/knockout globals (ko, KnockoutObservable...) for the first.ts
first.ts:
const obs : KnockoutObservable<string> = ko.observable("hello"); // should raise error TS2304: Cannot find name 'ko'. and error TS2304: Cannot find name 'KnockoutObservable'.
console.log(obs());
second.ts:
import * as ko from "knockout"; // this import makes 'ko' globally available even for first.ts
export class Foo {
bar = ko.observable("bar");
}
tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": true,
"sourceMap": false,
"declaration": false,
"noUnusedLocals": true,
"outDir": "dist",
"types": [
]
},
"exclude": [
"node_modules",
"dist"
]
}
The full solution is available here: https://github.com/kingatlas/typescript-sandbox
How can I prevent ko from being global an keep using it as a module (import ... from)?
Upvotes: 3
Views: 183
Reputation: 51579
There is no easy way. Knockout typings are following widespread pattern that allows to use them either as global or as a module. A side effect of that pattern is that variable ko
appears in global scope as soon as knockout typings are included in the compilation.
One workaround is to compile second.ts
and first.ts
separately, each with its own tsconfig.json
, and combine them later with bundler or module loader. To prevent first.ts
from accidentally importing knockout
, you need to have empty types
and typeRoots
in that tsconfig
, and list all typings explicitly in files
.
Another option is to make your own typings for knockout, declaring it only as a module. Again, you have to have empty types
and typeRoots
in tsconfig
to prevent typescript from accessing 'wrong' typings in node_moudles.
Upvotes: 2