【问题标题】:TypeScript with KnockoutJS带有 KnockoutJS 的 TypeScript
【发布时间】:2012-09-23 06:32:39
【问题描述】:

有没有使用 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());
});

【问题讨论】:

  • 我对与“var”结合使用的“declare”关键字感到有些困惑,直到我在规范中找到关于环境声明的部分。现在很有意义:typescriptlang.org/Content/….
  • 在 Typescript 0.9 中,我们有泛型,它为您提供输入的 observables:ko.observable<number>(10)。我写了一篇博文,提供了一些更详细的信息:ideasof.andersaberg.com/idea/12/…

标签: knockout.js typescript


【解决方案1】:

看看DefinitelyTyped

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

【讨论】:

  • 这可能是一个愚蠢的问题,但你能解释一下 TypeScript 类型定义到底是什么/做什么吗?纯粹是为了让您可以在 TypeScript 编译的文件中使用库函数而编译器不会抱怨吗?如果是这种情况,您不需要在应用程序中引用定义,只需在编译 ts 文件时,对吗?
  • 正是如此。如果您在记事本中编写打字稿代码,则只需要在编译时定义。另一方面,打字稿的一个优点是它更容易让视觉工作室(和其他通过插件的编辑器)智能理解你的代码,它可以帮助你自动完成和执行类型和错误检查(更多比 JavaScript)。这就是为什么我们使用 JavaScript 编写的代码的定义文件来提供 typescript 类型检查。当然,您可以将库声明为“任何”,但这并不好。希望我有所帮助!
  • 请注意,关键是将/// <reference path="knockout-2.2.d.ts" /> 添加到 .ts 文件的顶部,以便它获取定义。
  • 我在列表中的任何地方都看不到淘汰赛....已删除??搬家了??沮丧
【解决方案2】:

我制作了这个小接口来获取 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() 可以很容易地添加到相同的模式中。 更新:我修复了 subscribe() 的签名并添加了 computed() 和 observableArray() 的示例。

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

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

【讨论】:

  • @JcFx:Anders 提到的可能是采用 TypeScript .ts 文件并输出接口声明文件 .d.ts 的选项。没有办法使用常规的无类型 JavaScript 并神奇地发现类型。 JS 的问题(TypeScripts 试图解决的)是程序员无法声明她的意图,即变量应该符合特定类型。当您在 JS 中说 x = 'hello' 时,我们不知道您是否打算稍后在代码中的某个地方说 x = 34。我们无法推断出 x 的类型。
  • @JcFx:实际上,您可能是对的,一些有限的类型信息可以从纯 JS 派生。尝试时告诉我结果如何!
  • typescript 正在添加泛型。
【解决方案3】:

试试我的TypeScript接口声明的实现(附简单例子)
https://github.com/sv01a/TypeScript-Knockoutjs

【讨论】:

    【解决方案4】:

    在标记中声明淘汰绑定的方式方面没有任何改变,但是一旦为淘汰库编写接口,我们就会获得智能感知优势。在这方面,它就像jquery Sample 一样工作,它有一个typescript file containing interfaces for most of the jQuery api

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

    我必须这样做才能将 Visual Studio 模板项目移植到淘汰赛:

    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>
    

    【讨论】:

    • 不是在 ko 中发布给每个构造函数的那种矫枉过正
    【解决方案5】:

    好的,只需使用以下命令导入敲除类型或 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。

    希望这会有所帮助。

    【讨论】:

    • 这对 2021 年的我来说是完美的。在利用 npm 的同时将 Typescript 与现有的旧 Javascript 混合。谢谢。
    【解决方案6】:

    我正在使用https://www.nuget.org/packages/knockout.editables.TypeScript.DefinitelyTyped/ 并且它具有用于 Knockout 的所有接口。

    【讨论】:

      猜你喜欢
      • 2016-05-27
      • 2019-12-13
      • 2016-04-11
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 2015-09-13
      相关资源
      最近更新 更多