TypeScript con KnockoutJS


137

¿Hay alguna muestra del uso de TypeScript con KnockoutJS? ¿Tengo curiosidad por saber cómo trabajarían juntos?

Editar

Esto es lo que tengo, parece funcionar.

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

}

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

Esto genera el siguiente Javascript:

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

66
Estaba un poco confundido por la palabra clave "declarar" utilizada junto con "var" hasta que encontré la sección sobre Declaraciones ambientales en la especificación. Tiene mucho sentido ahora: typescriptlang.org/Content/… .
Rex Miller

2
En Letra de imprenta 0.9 tenemos los genéricos, que le da escrito observables: ko.observable<number>(10). Escribí una publicación de blog con
Anders

Respuestas:


108

Mira DefinitelyTyped .

"Depósito de definiciones de tipos de TypeScript para bibliotecas populares de JavaScript"


3
Esta puede ser una pregunta tonta, pero ¿puede explicar qué es / hace exactamente una definición de tipo TypeScript? ¿Es puramente para que pueda usar funciones de biblioteca en un archivo compilado TypeScript sin que el compilador se queje? Si ese es el caso, no necesitaría hacer referencia a la definición en su aplicación, justo cuando compila los archivos ts, ¿correcto?
innegablemente, el

9
Ese es exactamente el caso. Si estuviera escribiendo su código mecanografiado en el bloc de notas, solo necesitaría las definiciones en tiempo de compilación. Por otro lado, uno de los puntos positivos del mecanografiado es que es más fácil para el estudio visual (y otros editores a través de complementos) comprender su código y le ayuda mucho con la finalización automática y realizar la verificación de tipo y error (mucho más que JavaScript). Es por eso que utilizamos archivos de definición para el código escrito en JavaScript para proporcionar una verificación de tipo de mecanografiado. Por supuesto, podría declarar libs como "cualquiera", pero esto no es bueno. ¡Espero que ayude!
George Mavritsakis

55
Tenga en cuenta que la clave es agregar /// <reference path="knockout-2.2.d.ts" />a la parte superior de su archivo .ts para que recoja las definiciones.
Aidan Ryan

No veo knockout en ninguna parte de la lista ... eliminado? ¿¿movido?? frustrado
Jester

58

Hice esta pequeña interfaz para obtener tipos estáticos para 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;
    };
}

Póngalo en "Knockout.d.ts" y luego haga referencia a él desde sus propios archivos. Como puede ver, se beneficiaría enormemente de los genéricos (que vienen de acuerdo con las especificaciones).

Solo hice algunas interfaces para ko.observable (), pero ko.computed () y ko.observableArray () se pueden agregar fácilmente en el mismo patrón. Actualización: arreglé las firmas para subscribe () y agregué ejemplos de computed () y observableArray ().

Para usar desde su propio archivo, agregue esto en la parte superior:

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

2
@JcFx: a lo que se refería Anders probablemente era la opción de tomar un archivo .ts de TypeScript y generar un archivo de declaración de interfaz .d.ts. No hay forma de tomar JavaScript sin tipo y descubrir mágicamente los tipos. El problema con JS (que TypeScripts intenta resolver) es que no hay forma de que el programador declare su intención de que una variable se ajuste a un tipo en particular. Cuando dice x = 'hello'en JS, no sabemos si tenía la intención de decirlo en algún lugar posterior de su código x = 34. Hance no podemos inferir nada sobre el tipo de x.
Sten L

@JcFx: en realidad, es posible que tenga razón en que parte de la información de tipo limitada se pueda derivar de JS simple. ¡Hazme saber cómo te va cuando lo intentes!
Sten L

El mecanografiado está agregando genéricos.
Daniel A. White


6

Nada cambiaría en términos de la forma en que se declaran los enlaces de eliminación en el marcado; sin embargo, obtendríamos la bondad intellisense una vez que las interfaces se escriban para la biblioteca de eliminación. A este respecto, funcionaría igual que la muestra jquery , que tiene un archivo de mecanografía que contiene interfaces para la mayoría de la API jQuery .

Creo que si se deshace de las dos declaraciones de variables para ko y $, su código funcionará. Estos están ocultando las variables ko y $ reales que se crearon cuando se cargaron las secuencias de comandos knockout y jquery.

Tuve que hacer esto para portar el proyecto de plantilla de Visual Studio para eliminar:

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>

1
No está publicando en ko para cada tipo de construcción excesivo
Simon_Weaver

3

Ok, solo use el siguiente comando para importar los tipos de eliminación o tds.

npm install @types/knockout

Esto creará un directorio @types en el directorio node_modules de su proyecto y el archivo de definición de tipo de eliminación de índice estará en un directorio llamado eliminación. A continuación, a través de una referencia de triple barra al archivo de tipos. Esto le dará excelentes características de IDE y TypeScript.

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

Finalmente, solo use una declaración de declaración para llevar la variable ko al alcance. Esto está fuertemente tipado, así que hola intellisense.

declare var ko: KnockoutStatic;

Entonces ahora puede usar KO al igual que en sus archivos javascript.

ingrese la descripción de la imagen aquí

Espero que esto ayude.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.