1.TypeScript-Basic
2.TypeScript interface
3.Typescript-module(1)
4.TypeScript Modules(2)
5.Typescript tsconfig
6.TypeScript Functions
7.Typescript Classjavascript
CMD和AMD外部依賴模塊
若是你並無使用node.js或require.js,那就沒有必要使用module關鍵字了,只須要使用namespacejava
namespace中使用reference,module使用import someMod = require('someModule');
node
export功能不變,使module內部聲明外部可見typescript
編譯module,必須指定--module參數segmentfault
tsc --module commonjs Test.ts tsc --module amd Test.ts
編譯器根據import語句,順序導入依賴文件api
Validation.tsrequirejs
export interface StringValidator { isAcceptable(s: string): boolean; }
LettersOnlyValidator.tsui
import validation = require('./Validation'); var lettersRegexp = /^[A-Za-z]+$/; export class LettersOnlyValidator implements validation.StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } }
ZipCodeValidator.tsurl
import validation = require('./Validation'); var numberRegexp = /^[0-9]+$/; export class ZipCodeValidator implements validation.StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } }
Test.tsspa
import validation = require('./Validation'); import zip = require('./ZipCodeValidator'); import letters = require('./LettersOnlyValidator'); // Some samples to try var strings = ['Hello', '98052', '101']; // Validators to use var validators: { [s: string]: validation.StringValidator; } = {}; validators['ZIP code'] = new zip.ZipCodeValidator(); validators['Letters only'] = new letters.LettersOnlyValidator(); // Show whether each string passed each validator strings.forEach(s => { for (var name in validators) { console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name); } });
上述語法typescript編譯器是如何生成代碼的?
demo:
SimpleModule.ts
import m = require('mod'); export var t = m.something + 1;
AMD / RequireJS SimpleModule.js:
define(["require", "exports", 'mod'], function(require, exports, m) { exports.t = m.something + 1; });
CommonJS / Node SimpleModule.js:
var m = require('mod'); exports.t = m.something + 1;
export= 語法
在LettersOnlyValidator.ts中有下面的代碼
import validation = require('./Validation'); ... validation. StringValidator.doSometing();
同時咱們發現上面例子的兩種validator,每一個module都只導出一個class聲明。若是使用上面的方式導出,其餘文件import以後,每次都使用validation. StringValidator
顯得很沉重
Validation.ts
export interface StringValidator { isAcceptable(s: string): boolean; }
LettersOnlyValidator.ts
import validation = require('./Validation'); var lettersRegexp = /^[A-Za-z]+$/; class LettersOnlyValidator implements validation.StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } } export = LettersOnlyValidator;
ZipCodeValidator.ts
import validation = require('./Validation'); var numberRegexp = /^[0-9]+$/; class ZipCodeValidator implements validation.StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export = ZipCodeValidator;
Test.ts(此文件是重點,zipValidator和lettersValidator能夠直接使用)
import validation = require('./Validation'); import zipValidator = require('./ZipCodeValidator'); import lettersValidator = require('./LettersOnlyValidator'); // Some samples to try var strings = ['Hello', '98052', '101']; // Validators to use var validators: { [s: string]: validation.StringValidator; } = {}; validators['ZIP code'] = new zipValidator(); validators['Letters only'] = new lettersValidator(); // Show whether each string passed each validator strings.forEach(s => { for (var name in validators) { console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name); } });
注意
這種簡化寫法只使用於只導出一個聲明的模塊
另外一種縮短對象引用名稱的方式。
注意
別名的語法也是很奇葩的,若是名稱太長,可使用import q = x.y.z
,這個語法和import x = require('name')
沒有一毛錢關係,typescript項目組的朋友們,大家加個關鍵字能死嗎?這裏的語法只是爲指定的符號建立一個別名。
module Shapes { export module Polygons { export class Triangle { } export class Square { } } } import polygons = Shapes.Polygons; var sq = new polygons.Square(); // Same as 'new Shapes.Polygons.Square()'
有時候,你牢牢想在知足某些條件下,才加載某一模塊
這個功能確實很贊,可是仍是語法的問題,很讓你困惑。
再說以前呢,有必要對這個語法進行深刻了解
import zipValidator = require('./ZipCodeValidator');
按照上面的理解,大多數人確定認爲,這個語法就是nodejs中的var zipValidator = require('./ZipCodeValidator');
這樣理解也沒錯,可是這裏有一個typescript的惰性加載問題。首先咱們知道node加載外部模塊是很浪費時間的,因此呢,typescript遇到這句話,並不會立刻進行require調用,而是等到後面真的要用的該模塊時,纔會require.看例子:
Test.ts
import StringValidator = require('./Validation'); import zipValidator = require('./ZipCodeValidator'); import lettersValidator = require('./LettersOnlyValidator'); // Some samples to try var strings = ['Hello', '98052', '101']; // Validators to use var validators: { [s: string]: StringValidator; } = {}; validators['ZIP code'] = new zipValidator();
裏面的lettersValidator
雖然導入了,可是後面並無使用。
生成的js代碼以下:
var zipValidator = require('./ZipCodeValidator'); // Some samples to try var strings = ['Hello', '98052', '101']; // Validators to use var validators = {}; validators['ZIP code'] = new zipValidator();
ok,這就是咱們要了解的背景,typescript的惰性加載問題
利用上面的這個特性,咱們實現動態加載(nodejs和requirejs的區別)
Dynamic Module Loading in node.js
declare var require; import Zip = require('./ZipCodeValidator'); if (needZipValidation) { var x: typeof Zip = require('./ZipCodeValidator'); if (x.isAcceptable('.....')) { /* ... */ } }
Sample: Dynamic Module Loading in require.js
declare var require; import Zip = require('./ZipCodeValidator'); if (needZipValidation) { require(['./ZipCodeValidator'], (x: typeof Zip) => { if (x.isAcceptable('...')) { /* ... */ } }); }
雖然我前面鋪墊了不少,你看到這裏,仍是可能看不懂,好吧,我認可我本身在這裏也糾結了很久
declare var require
是表示聲明nodejs中的require關鍵詞,不然這裏var x: typeof Zip = require('./ZipCodeValidator');
,會報錯(require未聲明)。
請注意這裏的require是node中的require,而import Zip = require('./ZipCodeValidator');
中的require是typescript的關鍵詞,並且只能和import一塊兒用。瞭解這點很是重要!!!
import Zip = require('./ZipCodeValidator');
根據惰性加載機制,這句話什麼都不會作!!!
typeof Zip
什麼意思,請回頭看高級技巧
生成的js代碼
if (needZipValidation) { var x = require('./ZipCodeValidator'); if (x.isAcceptable('.....')) { } }
第三方庫都不是typescript開發的,咱們要使用的時候怎麼使用呢?
第三方庫api都是沒有類型信息的,可是typescript編譯器主要的工做就是檢查類型是否匹配。咱們能不能把它們的api所有聲明一遍,這樣咱們的代碼調用api的時候,編譯器去檢查聲明類型是否一致,來提示錯誤。
因此要寫.d.ts文件,好比D3,那就要寫D3.d.ts
namespace
D3.d.ts (simplified excerpt)
declare namespace D3 { export interface Selectors { select: { (selector: string): Selection; (element: EventTarget): Selection; }; } export interface Event { x: number; y: number; } export interface Base extends Selectors { event: Event; } } declare var d3: D3.Base;
module
node.d.ts (simplified excerpt)
declare module "url" { export interface Url { protocol?: string; hostname?: string; pathname?: string; } export function parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url; } declare module "path" { export function normalize(p: string): string; export function join(...paths: any[]): string; export var sep: string; }
Now we can /// <reference> node.d.ts and then load the modules using e.g. import url = require('url');.
///<reference path="node.d.ts"/> import url = require("url"); var myUrl = url.parse("http://www.typescriptlang.org");