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ć?


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...

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.


Niezbyt dobry pomysł przy używaniu webpacka, webpack będzie wymagał obecności tego modułu podczas transpilacji ...
— Akash Kava
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.