enenkey
enenkey

Reputation: 1271

global declarations made available for all files as soon as the associated declared module is imported

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

Answers (1)

artem
artem

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

Related Questions