带KnockoutJS的TypeScript


137

是否有将TypeScript与KnockoutJS一起使用的示例?我只是好奇他们如何一起工作?

编辑

这是我所拥有的,似乎可以正常工作

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

}

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

这将生成以下Javascript:

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

6
在将“ declare”关键字与“ var”结合使用时,我有些困惑,直到找到规范中有关“环境声明”的部分。现在非常合理typescriptlang.org/Content/…
雷克斯·米勒

2
在Typescript 0.9中,我们有泛型,它为您提供了可观察的类型:ko.observable<number>(10)。我写了一篇博文,其中包含一些更详细的信息:ideaof.andersaberg.com/idea/12/…–
Anders

Answers:


108

查看DefinitelyTyped

“流行的JavaScript库的TypeScript类型定义存储库”


3
这可能是一个愚蠢的问题,但是您能解释一下TypeScript类型定义到底是什么吗?纯粹是为了使您可以在TypeScript编译的文件中使用库函数而不会引起编译器的抱怨吗?如果是这样,您就不需要在应用程序中引用定义,仅在编译ts文件时,对吗?
无可否认的是

9
确实是这样。如果要在记事本中编写打字稿代码,则仅在编译时需要定义。另一方面,打字稿的优点之一是,Visual Studio(和其他通过插件的编辑器)的智能更容易理解您的代码,并且可以自动完成并执行类型和错误检查(更多内容)。比JavaScript)。这就是为什么我们将定义文件用于用JavaScript编写的代码,以便提供打字稿类型检查的原因。当然,您可以将libs声明为“ any”,但这不是很好。希望我有所帮助!
乔治·马夫里斯基斯基斯(

5
请注意,关键是添加/// <reference path="knockout-2.2.d.ts" />到.ts文件的顶部,以便它拾取定义。
艾丹·瑞安

我在列表中的任何地方都没有看到淘汰赛。感动了吗?沮丧
小丑

58

我做了这个小接口来获取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;
    };
}

将其放在“ Knockout.d.ts”中,然后从您自己的文件中引用它。如您所见,它将从仿制药(根据规范而来)中受益匪浅。

我只为ko.observable()创建了几个接口,但是可以很容易地以相同的模式添加ko.computed()和ko.observableArray()。更新:我修复了subscription()的签名,并添加了compute()和observableArray()的示例。

要在您自己的文件中使用,请在顶部添加:

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

2
@JcFx:Anders所指的可能是获取TypeScript .ts文件并输出接口声明文件.d.ts的选项。无法采用常规的无类型JavaScript并神奇地发现类型。JS(TypeScripts试图解决)的问题在于,程序员无法宣告其意图是变量应符合特定类型。当您x = 'hello'使用JS 说时,我们不知道您是否打算稍后在代码中说x = 34。因此,我们无法推断出x的类型。
Sten L

@JcFx:实际上,您可能是正确的,一些有限的类型信息可以从纯JS派生而来。让我知道尝试的过程!
Sten L '10

打字稿正在添加泛型。
丹尼尔·怀特


6

在标记中声明敲除绑定的方式不会发生任何变化,但是一旦为敲除库编写了接口,我们将获得智能感知优势。在这方面,它就像jquery Sample一样工作,后者具有一个包含大多数jQuery API接口打字稿文件

我认为,如果您摆脱了ko和$的两个变量声明,您的代码就可以工作。这些隐藏了在敲除和jquery脚本加载时创建的实际ko和$变量。

我必须这样做才能移植Visual Studio模板项目以进行剔除:

应用程式:

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
不会在ko中发布每种构造函数的过大杀伤力

3

好的,所以只需使用以下命令导入敲除类型或tds。

npm install @types/knockout

这将在您的项目的node_modules目录中创建一个@types目录,索引敲除类型定义文件将位于名为敲除的目录中。接下来,通过对类型文件的三斜杠引用。这将提供出色的IDE和TypeScript功能。

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

最后,只需使用一条声明语句将ko变量纳入范围即可。这是强类型的,因此您很聪明。

declare var ko: KnockoutStatic;

所以现在您可以像使用javascript文件一样使用KO。

在此处输入图片说明

希望这可以帮助。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.