TypeScript з KnockoutJS


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
Мене дещо плутає ключове слово "оголосити", яке використовується разом із "var", поки я не знайшов розділ про декларації про навколишнє середовище у специфікації. Має сенс зараз: typescriptlang.org/Content / ... .
Рекс Міллер

2
У друкованому 0.9 ми маємо Generics, яка дає вам надрукували спостерігаються: ko.observable<number>(10). Я написав допис у блозі з дещо детальнішою інформацією: ideaof.andersaberg.com/idea/12/…
Anders

Відповіді:


108

Подивіться на DefinitelyTyped .

"Сховище визначень типу TypeScript для популярних бібліотек JavaScript"


3
Це може бути німим питанням, але чи можете ви пояснити, що саме таке визначення типу TypeScript? Це суто так, що ви можете використовувати функції бібліотеки у файлі, складеному TypeScript, без компілятора скаржитися? Якщо це так, вам не потрібно буде посилатися на визначення у вашій програмі, саме коли ви збираєте файли ts, правильно?
безперечнороб

9
Саме так. Якщо ви писали свій код машинопису в блокнот, вам знадобляться лише визначення під час компіляції. З іншого боку, одним із хороших моментів машинопису є те, що візуальній студії (та іншим редакторам за допомогою плагінів) легше зрозуміти ваш код, і це допоможе вам значно покращити автоматичне завершення та виконати перевірку типу та помилок (багато іншого ніж JavaScript). Ось чому ми використовуємо файли визначення для коду, написаного на JavaScript, щоб забезпечити перевірку типу машинопису. Звичайно, ви можете оголосити libs як "будь-який", але це не добре. Сподіваюся, я допоміг!
Джордж Маврицакіс

5
Зауважте, що ключ полягає в тому, щоб додати /// <reference path="knockout-2.2.d.ts" />до верхнього файлу .ts, щоб він підбирав визначення.
Айдан Раян

Я ніде в списку не бачу нокауту .... видалено ?? переїхав ?? розчарований
Jester

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 () можна легко додати в одній схемі. Оновлення: я виправила підписи для підписки () та додала приклади computed () та observableArray ().

Щоб використовувати з власного файлу, додайте це вгорі:

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

2
@JcFx: Те, на що згадував Андерс, ймовірно, було можливість взяти файл TypeScript .ts та вивести файл декларації інтерфейсу .d.ts. Немає можливості приймати регулярний нетипізований JavaScript і магічно відкривати типи. Проблема JS (яку TypeScripts намагається вирішити) полягає в тому, що програміст не може заявити про свій намір, що змінна повинна відповідати конкретному типу. Коли ви говорите x = 'hello'в JS, ми не знаємо, чи ви мали намір десь пізніше у своєму коді сказати x = 34. Отже, ми не можемо зробити нічого висновку про тип x.
Sten L

@JcFx: насправді ви можете мати рацію, що деяка інформація обмеженого типу може бути отримана з простого JS. Дайте мені знати, як це відбувається, коли ви намагаєтеся!
Sten L

typecript додає дженерики.
Даніель А. Білий


6

Нічого не зміниться з точки зору того, як оголошуються прив'язки нокауту в розмітці, однак ми отримаємо інтелігенційну користь, як тільки інтерфейси будуть записані для номінальної бібліотеки. У цьому відношенні він би працював так само, як і зразок jquery , який має файл машинопису, що містить інтерфейси для більшості api jQuery .

Я думаю, якщо ви позбудетеся двох оголошень змінної для ko і ​​$, ваш код спрацює. Вони приховують фактичні змінні ko та $, які були створені під час завантаження скриптів нокауту та jquery.

Мені довелося це зробити, щоб передати проект шаблону візуальної студії до нокауту:

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
Не публікується в ко для всіх конструкторів надмірного рівня
Simon_Weaver

3

Гаразд, просто використовуйте наступну команду для імпорту типів нокауту або tds.

npm install @types/knockout

Це створить каталог @types у вашому каталозі node_modules проектів, а файл визначення типу нокауту індексу буде в каталозі з назвою нокаут. Далі, через потрійну похилу посилання на файл типів. Це дасть чудові функції IDE та TypeScript.

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

Нарешті, просто використовуйте заяву заявити, щоб привести змінну ko у сферу застосування. Це сильно набрано, так що привіт інтелігенція.

declare var ko: KnockoutStatic;

Тепер ви можете використовувати KO так само, як у файлах javascript.

введіть тут опис зображення

Сподіваюся, це допомагає.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.