背景
總所周知,TS需要編譯成JS才能在瀏覽器上跑,TS也能夠調用JS的方法。但是,有一個現成的第三方JS類庫擺在面前,讓它如何能在TS中使用,很多剛入坑的朋友往往不得其門而入。下面我就講講我的辦法吧。
1、直接翻譯
看了上面4個字,大家可能不會不約而同地眉頭一皺,立刻開噴:“喔靠,餿主意!”。我承認,這的確是個笨辦法,但是我的確這么做過。笨辦法也是辦法,重劍無鋒,大巧不工。
對於一些JS庫只有不到200-300行代碼,直接翻譯成TS又何妨呢?自己用TS重寫,跟找typings(很多不一定能找到)或者自己寫*.d.ts的時間其實差不了多少。自己動手,也能加深對庫的理解,夯實自己。
2、頁面引入 + 全局定義
如果對第一條不滿意,不用着急,咱還有別的辦法。第二招,其實也很簡單粗暴。所謂“頁面引入”就是最常規的用<script>
標簽把js直接在html頁面引入,然后“全局定義”,就是聲明一個變量跟JS的全局變量名或者方法名一樣。
下面用大家非常熟悉的jQuery舉例吧。
頁面里直接用<script>標簽引入jquery.js
<html> <head> <script type="text/javascript" src="js/jquery.min.js"></script> </head> <body>
......
TS中聲明全局變量
$
,然后就可以直接開擼
declare var $; class App { init(){ $("#msg").html("jquery引用成功!"); } }
簡單粗暴的副作用就是不夠優雅,聲明的全局變量$
的類型只能是any,這意味着還是弱類型變量,因此IDE中沒有任何的方法和屬性還有類型的提示。因而,完全失去了寫TS的樂趣。下面重點說說怎樣做到優雅。
3、類型定義文件(.d.ts)
相信閣下如果看本文之前百度過,肯定看過這種方法。說明,這是主流。所以,我也准備重點詳細地介紹一下。
- 首先,什么是類型定義文件?
應該有點類似於C++后綴名為.h的頭文件,用於聲明JS主文件的函數接口和變量類型的定義,並且把這些定義暴露給TS使用。有了.d.ts的定義之后,TS就能感知到JS庫相關的代碼提示了。
- 接着,如何得到.d.ts文件?
1.可以先去DefinitelyTyped找找碰碰運氣,一般很流行的庫也許會有。
2.用npm的typings查找獲取的,其實跟上面沒什么兩樣。
3.網上還能還有一些工具,據說根據js庫能夠反向生成.d.ts。我試了都不靠譜,如果是C#生成.d.ts的成功率我是敢打包票,但是對JS我就只能呵呵了。
4.最后,“拿來主義”都不行的情況下,只有自己動手豐衣足食了。
自己做.d.ts之前,先分析一下js庫的代碼,看看自己需要什么接口就定義什么。那些自己用不着的大可放過。
例如,我早前做的marked.js,節選一些代碼:
marked.options = marked.setOptions = function(opt) { merge(marked.defaults, opt); return marked; }; marked.getDefaults = function () { return { baseUrl: null, breaks: false, gfm: true, headerIds: true, headerPrefix: '', highlight: null, langPrefix: 'language-', mangle: true, pedantic: false, renderer: new Renderer(), sanitize: false, sanitizer: null, silent: false, smartLists: false, smartypants: false, tables: true, xhtml: false }; }; marked.defaults = marked.getDefaults(); /** * Expose */ marked.Parser = Parser; marked.parser = Parser.parse; marked.Renderer = Renderer; marked.TextRenderer = TextRenderer; marked.Lexer = Lexer; marked.lexer = Lexer.lex; marked.InlineLexer = InlineLexer; marked.inlineLexer = InlineLexer.output; marked.Slugger = Slugger; marked.parse = marked;
這一段,很直觀地看出它有什么接口可以暴露出來了。其實,我只需要一個parse
的方法足矣。那么,我的marked.d.ts就會這么寫。
interface MDOption { baseUrl?: string; breaks?: boolean; gfm?: boolean; headerIds?: boolean; headerPrefix?: string; highlight?: any; langPrefix?: string; mangle?: boolean; pedantic?: boolean; sanitize?: boolean; sanitizer?: any; silent?: boolean; smartLists?: boolean; smartypants?: boolean; tables?: boolean; xhtml?: boolean; } interface MarkDown { parse(src: string, opt?: MDOption, callback?: Function); } declare module "marked" { export = marked; } declare var marked: MarkDown;
方法定義只有MarkDown.parse
一個,外加一個MDOption
的結構定義。這樣,我在TS調用就能用得很舒服了!至於,最后幾行的declare為什么那么寫?那是TS語法的套路,我這里就不多做解釋,能用就行。好奇寶寶們可以進入傳送門深入理解一下。
最后說一下,.d.ts怎么使用。直接上代碼:
///<reference path="../typings/marked.d.ts" /> import * as marked from "marked"; var md_html = marked.parse("### Hello TypeScript");
1.引用路徑
2.引入模塊
3.使用方法
很簡單的三行代碼
至於,主體庫mark.js怎么引入頁面,方法很多,八仙過海各顯神通。我用的是require.js。
require.config({ paths: { 'jquery': '//g.alicdn.com/sj/lib/jquery/dist/jquery.min', 'marked': '/js/lib/marked.min' } });
OK,講完,收工。
作者:ChenReal
鏈接:https://www.jianshu.com/p/3b154d6e231b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。