1

This seems simple because the same code works well in simple JS file and it also has autocompletion for the ko variable's members. I have the following TypeScript code below:

// both of the following import lines result in: `ko` undefined

// import { ko } from "@tko/build.knockout";
import { ko } from "../node_modules/@tko/build.knockout/dist/build.knockout.es6";


alert("test: " + ko);

tsconfig.json

{
    "compilerOptions": {
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true,
        "outDir": "js",
        "target": "ES3",
        "watch": true,
        "allowJs": true,
        "lib": ["ES5", "DOM"],
        "module": "CommonJS"
    },
    "include": [
        "ts"
    ],
    "exclude": [
        "node_modules"
    ]
}

The test repo is here.

Using the given tsconfig.json file, I cannot import the ko4 package well. I could change some of the things in tsconfig.json but I do not know how to make it compatible with all the used modules in my main project. I chose to use ES6 import syntax because it is future-proof.

I would have used KnockOut v3.5 but it does not work with ES6 import syntax.

I also wish to mention that I use VS Code.

Thank you.

Update 1

(based on the answer from Nenad)

In tsconfig.json I had to set moduleResolution to "Node" (previously it was the default, in my case "classic").

I also had to create a package.json file in the root directory of my project. I thought I had one, but I had just a package-lock.json. After creating the package.json file, I rerun npm i and now VS Code understands the imports. I do not have to put a path to something inside the node_modules directory, I just put the name of the npm module.

I also had to replace KnockoutObservable with ko.Observable and all the other Knockout...-named classes and interfaces used in my project.

The remaining problem is that after I switched to the AMD module system the output file (bundle.js) does not contain all the needed modules, just the main.ts file converted to JS. Probably this is the subject of another question.

silviubogan
  • 3,343
  • 3
  • 31
  • 57

1 Answers1

2

If you get knockout version 3 via 'npm' or 'yarn':

yarn add knockout

All you have to do to import knockout is this:

import * as ko from "knockout";

This works because in node_modules\knockout folder you have package.json file with this lines (among others):

  "main": "build/output/knockout-latest.js",
  "types": "build/types/knockout.d.ts",

That is how typescript knows how to resolve from "knockout" to specific JavaScript file and also where to pull TypeScript types from. Types are bundled in the package.

Version 4

On the other side, if you download version 4: yarn add @tko/build.knockout it contains only:

  "main": "dist/build.knockout.js",

So correct way to import it is still:

import * as ko from "knockout";

However, you need to find TypeScript definitions separately and add them to the project. As far as I could see, for the version 4 they don't exist in the main GitHub repository.

Nenad
  • 24,809
  • 11
  • 75
  • 93
  • If I use v3 I get this error: `ko4-test/ts/main.ts(5,10): Error TS2305: Module '"../node_modules/knockout/build/types/knockout"' has no exported member 'ko'.` Please help me. Thank you. – silviubogan Apr 09 '20 at 09:55
  • I solved that. Now I get `Namespace '"/my-project/node_modules/knockout/build/types/knockout"' has no exported member 'KnockoutObservable'`. Example code where the error shows up: `class PageViewModel { language: ko.KnockoutObservable;`. How can I use `KnockoutObservable`? At the top of the file I have `import * as ko from "knockout";`. – silviubogan Apr 09 '20 at 10:25
  • 'v3' means you switched to version 3 now? Which example code? Observable should be `ko.observarble()`. You are right about the import `import * as ko from "knockout";` – Nenad Apr 09 '20 at 10:39
  • Yes, I switched to v3. It seems that I have a smaller problem now: `ParseError: 'import' and 'export' may appear only with 'sourceType: module'` because I export a class although I intended it to be static (it has only static members). – silviubogan Apr 09 '20 at 10:42
  • Additionally, why are you targeting "es3" and not "es5" and why "commonjs", not "amd", if it's for browser? – Nenad Apr 09 '20 at 10:43
  • I could not think about all the possible combinations of the variables in tsconfig.json. I will use amd then. Thank you. – silviubogan Apr 09 '20 at 10:46
  • For the error regarding import and export, it's going out of scope of this question. Ask another question. Make it reproducable. Type you were asking for is `ko.Observable`. Those are all different questions. – Nenad Apr 09 '20 at 10:47
  • I am happy if you can help me with this too: https://stackoverflow.com/q/61121230/258462. Thank you. – silviubogan Apr 09 '20 at 12:33