TypeScript with KnockoutJS

knockout.jsTypescript

knockout.js Problem Overview


Is there any sample of using TypeScript with KnockoutJS? I'm just curious as to how they would work together?

Edit

Here is what I have, seems to work

declare var ko: any;
declare var $: any;
class ViewModel {
    x = ko.observable(10);
    y = ko.observable(10);

}

$(() => {
    ko.applyBindings(new ViewModel());
});

This generates into the following Javascript:

var ViewModel = (function () {
    function ViewModel() {
        this.x = ko.observable(10);
        this.y = ko.observable(10);
    }
    return ViewModel;
})();
$(function () {
    ko.applyBindings(new ViewModel());
});

knockout.js Solutions


Solution 1 - knockout.js

Look at DefinitelyTyped.

"TypeScript type definitions repository for popular JavaScript libraries"

Solution 2 - knockout.js

I made this little interface to get static types for Knockout:

interface ObservableNumber {
		(newValue: number): void;				
		(): number;								
		subscribe: (callback: (newValue: number) => void) => void;
}
interface ObservableString {
		(newValue: string): void;				
		(): string;								
		subscribe: (callback: (newValue: string) => void) => void;
}
interface ObservableBool {
	(newValue: bool): void;				
	(): bool;								
	subscribe: (callback: (newValue: bool) => void) => void;
}

interface ObservableAny {
	(newValue: any): void;				
	(): any;								
	subscribe: (callback: (newValue: any) => void) => void;
}

interface ObservableStringArray {
	(newValue: string[]): void;
	(): string[];
	remove: (value: String) => void;
	removeAll: () => void;
	push: (value: string) => void;
	indexOf: (value: string) => number;
}

interface ObservableAnyArray {
	(newValue: any[]): void;
	(): any[];
	remove: (value: any) => void;
	removeAll: () => void;
	push: (value: any) => void;
}

interface Computed {
	(): any;
}

interface Knockout {
	observable: {
		(value: number): ObservableNumber;
		(value: string): ObservableString;
		(value: bool): ObservableBool;
		(value: any): ObservableAny;
	};
	observableArray: {
		(value: string[]): ObservableStringArray;
		(value: any[]): ObservableAnyArray;
	};
	computed: {
		(func: () => any): Computed;
	};
}

Put it in "Knockout.d.ts" and then reference it from your own files. As you can see, it would benefit greatly from generics (which are coming according to the specs).

I only made a few interfaces for ko.observable(), but ko.computed() and ko.observableArray() can be easily added in the same pattern. Update: I fixed the signatures for subscribe() and added examples of computed() and observableArray().

To use from your own file, add this at the top:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;

Solution 3 - knockout.js

Try my realisation of TypeScript interface declarations (with simple example)
https://github.com/sv01a/TypeScript-Knockoutjs

Solution 4 - knockout.js

Nothing would change in terms of the way knockout bindings are declared in the markup however we would get the intellisense goodness once the interfaces are written for the knockout library. In this respect it would work just like the jquery Sample, which has a typescript file containing interfaces for most of the jQuery api.

I think if you get rid of the two variable declarations for ko and $ your code will work. These are hiding the actual ko and $ variables that were created when the knockout and jquery scripts loaded.

I had to do this to port the visual studio template project to knockout:

app.ts:

class GreeterViewModel {
    timerToken: number;
    utcTime: any;

    constructor (ko: any) { 
        this.utcTime = ko.observable(new Date().toUTCString());
        this.start();
    }

    start() {
        this.timerToken = setInterval(() => this.utcTime(new Date().toUTCString()), 500);
    }
}

window.onload = () => {
    // get a ref to the ko global
    var w: any;
    w = window;
    var myKO: any;
    myKO = w.ko;

    var el = document.getElementById('content');
    myKO.applyBindings(new GreeterViewModel(myKO), el);
};

default.htm:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>TypeScript HTML App</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="Scripts/knockout-2.1.0.debug.js" type="text/javascript"></script>
    <script src="app.js"></script>
</head>
<body>
    <h1>TypeScript HTML App</h1>

    <div id="content" data-bind="text: utcTime" />
</body>
</html>

Solution 5 - knockout.js

Ok so just use the following command to import the knockout types or tds.

npm install @types/knockout

This will create a @types directory in your projects node_modules directory and the index knockout type definition file will be in a directory named knockout. Next, through a triple-slash reference to the types file. This will give great IDE and TypeScript features.

/// <reference path="../node_modules/@types/knockout/index.d.ts" />

Finally, just use a declare statement to bring the ko variable into scope. This is strongly-typed so hello intellisense.

declare var ko: KnockoutStatic;

So now you can use KO just like in your javascript files.

enter image description here

Hope this helps.

Solution 6 - knockout.js

I am using https://www.nuget.org/packages/knockout.editables.TypeScript.DefinitelyTyped/ and it has all interfaces for Knockout.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCallumVassView Question on Stackoverflow
Solution 1 - knockout.jsGeorge MavritsakisView Answer on Stackoverflow
Solution 2 - knockout.jsSten LView Answer on Stackoverflow
Solution 3 - knockout.jsSv01aView Answer on Stackoverflow
Solution 4 - knockout.jsJeremy DanyowView Answer on Stackoverflow
Solution 5 - knockout.jsSimperTView Answer on Stackoverflow
Solution 6 - knockout.jsJavaScript LinqView Answer on Stackoverflow