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
Меня несколько смущало ключевое слово «declare», используемое вместе с «var», пока я не нашел в спецификации раздел об объявлениях окружения. Теперь все имеет смысл: typescriptlang.org/Content/… .
Рекс Миллер
2
В машинописном 0.9 мы имеем Generics, которая дает вам напечатали наблюдаемые: ko.observable<number>(10). Я написал сообщение в блоге с более подробной информацией: ideasof.andersaberg.com/idea/12/…
Андерс,

Ответы:

108

Посмотрите на DefinficTyped .

"Репозиторий определений типов TypeScript для популярных библиотек JavaScript"

Георгий Маврицакис
источник
3
Это может быть глупый вопрос, но можете ли вы объяснить, что именно представляет / делает определение типа TypeScript? Это чисто для того, чтобы вы могли использовать библиотечные функции в файле, скомпилированном с помощью TypeScript, без жалоб компилятора? Если это так, вам не нужно ссылаться на определение в вашем приложении, просто когда вы компилируете файлы ts, верно?
undeniablyrob
9
Это именно тот случай. Если бы вы писали свой машинописный код в блокноте, вам понадобились бы определения только во время компиляции. С другой стороны, одним из хороших моментов машинописного текста является то, что визуальной студии (и другим редакторам через плагины) легче понять ваш код, и он очень помогает вам с автоматическим завершением и выполнением проверки типов и ошибок (гораздо больше чем JavaScript). Вот почему мы используем файлы определений для кода, написанного на JavaScript, чтобы обеспечить проверку типов машинописного текста. Конечно, вы можете объявить библиотеки как «любые», но это нехорошо. Надеюсь, я помог!
Георгий Маврицакис 01
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 () можно легко добавить по тому же шаблону. Обновление: я исправил подписи для subscribe () и добавил примеры computed () и observableArray ().

Чтобы использовать из собственного файла, добавьте это вверху:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;
Sten L
источник
2
@JcFx: Андерс, вероятно, имел в виду вариант взять файл TypeScript .ts и вывести файл объявления интерфейса .d.ts. Невозможно взять обычный нетипизированный JavaScript и волшебным образом обнаружить типы. Проблема с JS (которую TypeScripts пытается решить) заключается в том, что программист не может заявить о своем намерении, чтобы переменная соответствовала определенному типу. Когда вы говорите x = 'hello'на JS, мы не знаем, собирались ли вы сказать где-нибудь позже в коде x = 34. Hance, мы ничего не можем сделать о типе x.
Sten L
@JcFx: возможно, вы правы, что некоторая ограниченная информация о типах может быть получена из простого JS. Дай мне знать, как дела, когда попробуешь!
Sten L
typescript добавляет дженерики.
Дэниел А. Уайт
6

Ничего не изменится в плане того, как привязки нокаутов объявляются в разметке, однако мы получим доброту intellisense, когда интерфейсы будут написаны для библиотеки нокаутов. В этом отношении он будет работать так же, как образец jquery , в котором есть файл машинописного текста, содержащий интерфейсы для большей части jQuery api .

Я думаю, что если вы избавитесь от двух объявлений переменных для ko и $, ваш код будет работать. Они скрывают фактические переменные ko и $, которые были созданы при загрузке скриптов knockout и jquery.

Мне пришлось сделать это, чтобы перенести проект шаблона 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>
Джереми Даньоу
источник
1
Не отправляет ко всем конструкторам
излишний
3

Хорошо, просто используйте следующую команду, чтобы импортировать типы нокаута или tds.

npm install @types/knockout

Это создаст каталог @types в каталоге node_modules ваших проектов, а файл определения типа нокаута индекса будет в каталоге с именем knockout. Затем через тройную косую черту ссылку на файл типов. Это даст отличные возможности IDE и TypeScript.

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

Наконец, просто используйте оператор declare, чтобы ввести переменную ko в область видимости. Это строго типизировано, так что здравствуйте, intellisense.

declare var ko: KnockoutStatic;

Итак, теперь вы можете использовать KO так же, как в ваших файлах javascript.

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

Надеюсь это поможет.

SimperT
источник