Jak używać zewnętrznej biblioteki bez maszynopisu z maszynopisu bez .d.ts?

100

Zdefiniowałem to w moim pliku .html:

<script type="text/javascript" src="bower_components/tree.js/tree.min.js"></script>
<script type="text/javascript" src="bower_components/q/q.js"></script>
<script type="text/javascript" src="test.js"></script>

Następnie w test.js:

 var myTree = Tree.tree({})

Ale błędy maszynopisu mówią: „Nie można znaleźć nazwy 'Drzewo'”

Próbowałem również skompilować --module amdi umieścić import Tree = require("model/tree");na górze pliku test.js, ale znowu się wyświetla błąd: Cannot find external module 'model/tree'.jednak wyraźnie powinien to być prawidłowy import, zobacz tutaj, gdzie został zdefiniowany: https://github.com/marmelab/tree .js / blob / master / src / main.js

Ja nie chce zapisywać pliki .d.ts dla każdego zewnętrznego pliku javascript chcę użyć, jest to, że poważnie co Typescript chce mi zrobić?

Blub
źródło
1
Nie musisz pisać plików .d.ts. Zobacz na stackoverflow.com/questions/27273489/ ... przykład
xmojmr
interesujące, to jednak nadal wymagałoby ode mnie deklarowania obiektów. Miałem wrażenie, że Typescript jest w pełni kompatybilny z javascriptem. Myślę, że ma to sens z punktu widzenia Typescript, jakoś musi odczytać kod i gdyby nie miał dobrze odniesień, byłyby to błędy.
Blub

Odpowiedzi:

124

Nie chcę zapisywać plików .d.ts dla każdego zewnętrznego pliku javascript, którego chcę użyć. Czy na poważnie tego oczekuje ode mnie Typescript?

Nie. Najprostszym / najszybszym rozwiązaniem jest po prostu stwierdzenie, że istnieje jakaś zmienna Tree. To jest tak proste, jak:

declare var Tree:any; // Magic
var myTree = Tree.tree({})

TypeSafety to przesuwana skala w języku TypeScript. W tym przypadku mówisz tylko kompilatorowi, że istnieje coś, co się nazywa Tree, że będziesz zarządzać i nie przejmujesz się zbyt dużym bezpieczeństwem typów poza faktem, że istnieje .

Więcej

IMHO: declare var Tree:any;Składnia tego wiersza jest znacznie prostsza niż w przypadku innych narzędzi JS do weryfikacji błędów, które wymagałyby pisania deklaracji użycia zmiennych, których nie ma w kodzie.

Aktualizacja

interface ITree {
    .. further methods and properties...
}

interface ITreeFactory {
    tree(input: { [key: string]: any }): Itree
};

declare var Tree: ITreeFactory; // magic...
basarat
źródło
Narzekało na mnie, kiedy użyłem tej metody. Musiałem użyć metody przedstawionej przez Anton poniżej. Twój przebieg może się jednak różnić! Dzięki za odpowiedź basarat.
Tiz
możesz także określić typ jako interfejs zamiast takiego, który zapewni lepszą inteligencję.
Akash Kava,
24

Możesz samodzielnie zdefiniować `` wymagania '' i użyć nieudokumentowanej funkcji zależności od amd w TypeScript:

/// <amd-dependency path="model/tree" />
declare var require:(moduleId:string) => any;
var Tree = require("model/tree");

Dyrektywa 'amd-dependency' powie kompilatorowi, aby dołączył Twój moduł do "zdefiniowania" argumentów w generowanym kodzie: zobacz przykład tutaj .

Możesz również zapoznać się z bardzo dobrym artykułem, w którym wyjaśniono, jak używać TypeScript z RequireJS.

Pamiętaj jednak, że bez napisania odpowiednich definicji TypeScript dla istniejącego kodu nie otrzymasz żadnych informacji o typie, a więc nie otrzymasz kontroli bezpieczeństwa typów, zaawansowanego uzupełniania kodu w narzędziach i tak dalej. Tak więc Twoje 'Drzewo' będzie faktycznie typu 'any' i faktycznie będzie dynamicznym fragmentem JS wewnątrz innego kodu TS.

Anton
źródło
Niezbyt dobry pomysł przy używaniu webpacka, webpack będzie wymagał obecności tego modułu podczas transpilacji ...
Akash Kava