TypeScript avec KnockoutJS

137

Existe-t-il un exemple d'utilisation de TypeScript avec KnockoutJS? Je suis juste curieux de savoir comment ils travailleraient ensemble?

Éditer

Voici ce que j'ai, semble fonctionner

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

}

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

Cela génère le Javascript suivant:

var ViewModel = (function () {
    function ViewModel() {
        this.x = ko.observable(10);
        this.y = ko.observable(10);
    }
    return ViewModel;
})();
$(function () {
    ko.applyBindings(new ViewModel());
});
CallumVass
la source
6
J'ai été quelque peu confus par le mot clé "declare" utilisé en conjonction avec "var" jusqu'à ce que je trouve la section sur les déclarations ambiantes dans la spécification. Cela prend tout son sens maintenant: typescriptlang.org/Content/… .
Rex Miller
2
Dactylographiée 0,9 nous avons Generics, qui vous donne saisi observables: ko.observable<number>(10). J'ai écrit un article de blog avec des informations plus détaillées: ideasof.andersaberg.com/idea/12/…
Anders

Réponses:

108

Regardez DefinatelyTyped .

«Référentiel de définitions de type TypeScript pour les bibliothèques JavaScript populaires»

George Mavritsakis
la source
3
Cela peut être une question stupide, mais pouvez-vous expliquer ce qu'est / fait exactement une définition de type TypeScript? Est-ce uniquement pour que vous puissiez utiliser des fonctions de bibliothèque dans un fichier compilé TypeScript sans que le compilateur ne se plaint? Si tel est le cas, vous n'aurez pas besoin de référencer la définition dans votre application, juste au moment de compiler les fichiers ts, n'est-ce pas?
undeniablyrob
9
C'est exactement le cas. Si vous écriviez votre code dactylographié dans le bloc-notes, vous n'auriez besoin que des définitions au moment de la compilation. D'un autre côté, l'un des bons points de la dactylographie est qu'il est plus facile pour l'intellisence du studio visuel (et d'autres éditeurs via des plugins) de comprendre votre code et cela vous aide beaucoup à la complétion automatique et à effectuer une vérification de type et d'erreurs (beaucoup plus que JavaScript). C'est pourquoi nous utilisons des fichiers de définition pour le code écrit en JavaScript afin de fournir une vérification de type dactylographiée. Bien sûr, vous pouvez déclarer libs comme "any", mais ce n'est pas bon. J'espère que j'ai aidé!
George Mavritsakis
5
Notez que la clé est d'ajouter /// <reference path="knockout-2.2.d.ts" />en haut de votre fichier .ts pour qu'il récupère les définitions.
Aidan Ryan
Je ne vois KO nulle part dans la liste .... supprimé ?? déplacé?? frustré
Jester
58

J'ai créé cette petite interface pour obtenir des types statiques pour 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;
    };
}

Mettez-le dans "Knockout.d.ts" puis référencez-le à partir de vos propres fichiers. Comme vous pouvez le voir, il bénéficierait grandement des génériques (qui arrivent selon les spécifications).

Je n'ai fait que quelques interfaces pour ko.observable (), mais ko.computed () et ko.observableArray () peuvent être facilement ajoutés dans le même modèle. Mise à jour: J'ai corrigé les signatures pour subscribe () et ajouté des exemples de computed () et observableArray ().

Pour utiliser à partir de votre propre fichier, ajoutez ceci en haut:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;
Sten L
la source
2
@JcFx: Ce à quoi Anders faisait référence était probablement l'option de prendre un fichier TypeScript .ts et de sortir un fichier de déclaration d'interface .d.ts. Il n'y a aucun moyen de prendre du JavaScript non typé régulier et de découvrir par magie les types. Le problème avec JS (que TypeScripts essaie de résoudre) est qu'il n'y a aucun moyen pour le programmeur de déclarer son intention qu'une variable doit se conformer à un type particulier. Quand vous dites x = 'hello'dans JS, nous ne savons pas si vous aviez l'intention de dire quelque part plus tard dans votre code x = 34. Hance nous ne pouvons rien déduire du type de x.
Sten L
@JcFx: en fait, vous avez peut-être raison de dire que certaines informations de type limitées pourraient être dérivées de JS brut. Faites-moi savoir comment ça se passe lorsque vous essayez!
Sten L
typescript ajoute des génériques.
Daniel A. White
6

Rien ne changerait en ce qui concerne la façon dont les liaisons knockout sont déclarées dans le balisage, mais nous obtiendrions la bonté intellisense une fois que les interfaces sont écrites pour la bibliothèque knockout. À cet égard, cela fonctionnerait exactement comme l' exemple jquery , qui a un fichier dactylographié contenant des interfaces pour la plupart des API jQuery .

Je pense que si vous vous débarrassez des deux déclarations de variables pour ko et $, votre code fonctionnera. Celles-ci masquent les variables ko et $ réelles qui ont été créées lors du chargement des scripts knockout et jquery.

J'ai dû faire cela pour porter le projet de modèle de studio visuel à 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>
Jeremy Danyow
la source
1
Ne
publie
3

Ok, utilisez simplement la commande suivante pour importer les types de knockout ou tds.

npm install @types/knockout

Cela créera un répertoire @types dans le répertoire node_modules de vos projets et le fichier de définition du type de knockout d'index sera dans un répertoire nommé knockout. Ensuite, par une référence triple barre oblique au fichier de types. Cela donnera d'excellentes fonctionnalités IDE et TypeScript.

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

Enfin, utilisez simplement une instruction declare pour mettre la variable ko dans la portée. Ceci est fortement typé alors bonjour intellisense.

declare var ko: KnockoutStatic;

Alors maintenant, vous pouvez utiliser KO comme dans vos fichiers javascript.

entrez la description de l'image ici

J'espère que cela t'aides.

SimperT
la source