在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ TypeScript 1.8
初始化項(xiàng)目結(jié)構(gòu)
聯(lián)合類型
介紹
介紹
介紹
編譯選項(xiàng)
TypeScript 1.6
介紹
介紹
發(fā)展路線圖
介紹
在MSBuild里使用編譯選項(xiàng)
可迭代性
TypeScript 1.3
介紹
介紹
TypeScript 1.1
變量聲明
即將到來的Angular 2框架是使用TypeScript開發(fā)的。 因此Angular和TypeScript一起使用非常簡單方便
tsconfig.json
介紹
介紹
介紹
在MSBuild里使用編譯選項(xiàng)
使用TypeScript的每日構(gòu)建版本
新建工程
枚舉
三斜線指令
結(jié)合ASP.NET v5使用TypeScript
TypeScript里的this
介紹
TypeScript 1.4
編碼規(guī)范
介紹
模塊解析
ASP.NET 4
架構(gòu)概述
介紹
介紹
ASP.NET Core
TypeScript 1.8
介紹
介紹
創(chuàng)建簡單工程
TypeScript 1.7
TypeScript 1.5
NPM包的類型
支持TypeScript的編輯器

TypeScript 1.8

類型參數(shù)約束

在 TypeScript 1.8 中, 類型參數(shù)的限制可以引用自同一個(gè)類型參數(shù)列表中的類型參數(shù). 在此之前這種做法會(huì)報(bào)錯(cuò). 這種特性通常被叫做 F-Bounded Polymorphism.

例子

function assign<T extends U, U>(target: T, source: U): T {
    for (let id in source) {
        target[id] = source[id];
    }
    return target;
}

let x = { a: 1, b: 2, c: 3, d: 4 };
assign(x, { b: 10, d: 20 });
assign(x, { e: 0 });  // 錯(cuò)誤

控制流錯(cuò)誤分析

TypeScript 1.8 中引入了控制流分析來捕獲開發(fā)者通常會(huì)遇到的一些錯(cuò)誤.

詳情見接下來的內(nèi)容, 可以上手嘗試:

cfa

不可及的代碼

一定無法在運(yùn)行時(shí)被執(zhí)行的語句現(xiàn)在會(huì)被標(biāo)記上代碼不可及錯(cuò)誤. 舉個(gè)例子, 在無條件限制的 return, throw, break 或者 continue 后的語句被認(rèn)為是不可及的. 使用 --allowUnreachableCode 來禁用不可及代碼的檢測和報(bào)錯(cuò).

例子

這里是一個(gè)簡單的不可及錯(cuò)誤的例子:

function f(x) {
    if (x) {
       return true;
    }
    else {
       return false;
    }

    x = 0; // 錯(cuò)誤: 檢測到不可及的代碼.
}

這個(gè)特性能捕獲的一個(gè)更常見的錯(cuò)誤是在 return 語句后添加換行:

function f() {
    return            // 換行導(dǎo)致自動(dòng)插入的分號(hào)
    {
        x: "string"   // 錯(cuò)誤: 檢測到不可及的代碼.
    }
}

因?yàn)?JavaScript 會(huì)自動(dòng)在行末結(jié)束 return 語句, 下面的對(duì)象字面量變成了一個(gè)代碼塊.

未使用的標(biāo)簽

未使用的標(biāo)簽也會(huì)被標(biāo)記. 和不可及代碼檢查一樣, 被使用的標(biāo)簽檢查也是默認(rèn)開啟的. 使用 --allowUnusedLabels 來禁用未使用標(biāo)簽的報(bào)錯(cuò).

例子

loop: while (x > 0) {  // 錯(cuò)誤: 未使用的標(biāo)簽.
    x++;
}

隱式返回

JS 中沒有返回值的代碼分支會(huì)隱式地返回 undefined. 現(xiàn)在編譯器可以將這種方式標(biāo)記為隱式返回. 對(duì)于隱式返回的檢查默認(rèn)是被禁用的, 可以使用 --noImplicitReturns 來啟用.

例子

function f(x) { // 錯(cuò)誤: 不是所有分支都返回了值.
    if (x) {
        return false;
    }

    // 隱式返回了 `undefined`
}

Case 語句貫穿

TypeScript 現(xiàn)在可以在 switch 語句中出現(xiàn)貫穿的幾個(gè)非空 case 時(shí)報(bào)錯(cuò). 這個(gè)檢測默認(rèn)是關(guān)閉的, 可以使用 --noFallthroughCasesInSwitch 啟用.

例子

switch (x % 2) {
    case 0: // 錯(cuò)誤: switch 中出現(xiàn)了貫穿的 case.
        console.log("even");

    case 1:
        console.log("odd");
        break;
}

然而, 在下面的例子中, 由于貫穿的 case 是空的, 并不會(huì)報(bào)錯(cuò):

switch (x % 3) {
    case 0:
    case 1:
        console.log("Acceptable");
        break;

    case 2:
        console.log("This is *two much*!");
        break;
}

React 無狀態(tài)的函數(shù)組件

TypeScript 現(xiàn)在支持無狀態(tài)的函數(shù)組件. 它是可以組合其他組件的輕量級(jí)組件.

// 使用參數(shù)解構(gòu)和默認(rèn)值輕松地定義 'props' 的類型
const Greeter = ({name = 'world'}) => <div>Hello, {name}!</div>;

// 參數(shù)可以被檢驗(yàn)
let example = <Greeter name='TypeScript 1.8' />;

如果需要使用這一特性及簡化的 props, 請確認(rèn)使用的是最新的 react.d.ts.

簡化的 React props 類型管理

在 TypeScript 1.8 配合最新的 react.d.ts (見上方) 大幅簡化了 props 的類型聲明.

具體的:

  • 你不再需要顯式的聲明 refkey 或者 extend React.Props
  • refkey 屬性會(huì)在所有組件上擁有正確的類型.
  • ref 屬性在無狀態(tài)函數(shù)組件上會(huì)被正確地禁用.

在模塊中擴(kuò)充全局或者模塊作用域

用戶現(xiàn)在可以為任何模塊進(jìn)行他們想要, 或者其他人已經(jīng)對(duì)其作出的擴(kuò)充. 模塊擴(kuò)充的形式和過去的包模塊一致 (例如 declare module "foo" { } 這樣的語法), 并且可以直接嵌在你自己的模塊內(nèi), 或者在另外的頂級(jí)外部包模塊中.

除此之外, TypeScript 還以 declare global { } 的形式提供了對(duì)于_全局_聲明的擴(kuò)充. 這能使模塊對(duì)像 Array 這樣的全局類型在必要的時(shí)候進(jìn)行擴(kuò)充.

模塊擴(kuò)充的名稱解析規(guī)則與 importexport 聲明中的一致. 擴(kuò)充的模塊聲明合并方式與在同一個(gè)文件中聲明是相同的.

不論是模塊擴(kuò)充還是全局聲明擴(kuò)充都不能向頂級(jí)作用域添加新的項(xiàng)目 - 它們只能為已經(jīng)存在的聲明添加 "補(bǔ)丁".

例子

這里的 map.ts 可以聲明它會(huì)在內(nèi)部修改在 observable.ts 中聲明的 Observable 類型, 添加 map 方法.

// observable.ts
export class Observable<T> {
    // ...
}
// map.ts
import { Observable } from "./observable";

// 擴(kuò)充 "./observable"
declare module "./observable" {

    // 使用接口合并擴(kuò)充 'Observable' 類的定義
    interface Observable<T> {
        map<U>(proj: (el: T) => U): Observable<U>;
    }

}

Observable.prototype.map = /*...*/;
// consumer.ts
import { Observable } from "./observable";
import "./map";

let o: Observable<number>;
o.map(x => x.toFixed());

相似的, 在模塊中全局作用域可以使用 declare global 聲明被增強(qiáng):

例子

// 確保當(dāng)前文件被當(dāng)做一個(gè)模塊.
export {};

declare global {
    interface Array<T> {
        mapToNumbers(): number[];
    }
}

Array.prototype.mapToNumbers = function () { /* ... */ }

字符串字面量類型

接受一個(gè)特定字符串集合作為某個(gè)值的 API 并不少見. 舉例來說, 考慮一個(gè)可以通過控制動(dòng)畫的漸變讓元素在屏幕中滑動(dòng)的 UI 庫:

declare class UIElement {
    animate(options: AnimationOptions): void;
}

interface AnimationOptions {
    deltaX: number;
    deltaY: number;
    easing: string; // 可以是 "ease-in", "ease-out", "ease-in-out"
}

然而, 這容易產(chǎn)生錯(cuò)誤 - 當(dāng)用戶錯(cuò)誤不小心錯(cuò)誤拼寫了一個(gè)合法的值時(shí), 并沒有任何提示:

// 沒有報(bào)錯(cuò)
new UIElement().animate({ deltaX: 100, deltaY: 100, easing: "ease-inout" });

在 TypeScript 1.8 中, 我們新增了字符串字面量類型. 這些類型和字符串字面量的寫法一致, 只是寫在類型的位置.

用戶現(xiàn)在可以確保類型系統(tǒng)會(huì)捕獲這樣的錯(cuò)誤. 這里是我們使用了字符串字面量類型的新的 AnimationOptions:

interface AnimationOptions {
    deltaX: number;
    deltaY: number;
    easing: "ease-in" | "ease-out" | "ease-in-out";
}

// 錯(cuò)誤: 類型 '"ease-inout"' 不能復(fù)制給類型 '"ease-in" | "ease-out" | "ease-in-out"'
new UIElement().animate({ deltaX: 100, deltaY: 100, easing: "ease-inout" });

更好的聯(lián)合/交叉類型接口

TypeScript 1.8 優(yōu)化了源類型和目標(biāo)類型都是聯(lián)合或者交叉類型的情況下的類型推導(dǎo). 舉例來說, 當(dāng)從 string | string[] 推導(dǎo)到 string | T 時(shí), 我們將類型拆解為 string[]T, 這樣就可以將 string[] 推導(dǎo)為 T.

例子

type Maybe<T> = T | void;

function isDefined<T>(x: Maybe<T>): x is T {
    return x !== undefined && x !== null;
}

function isUndefined<T>(x: Maybe<T>): x is void {
    return x === undefined || x === null;
}

function getOrElse<T>(x: Maybe<T>, defaultValue: T): T {
    return isDefined(x) ? x : defaultValue;
}

function test1(x: Maybe<string>) {
    let x1 = getOrElse(x, "Undefined");         // string
    let x2 = isDefined(x) ? x : "Undefined";    // string
    let x3 = isUndefined(x) ? "Undefined" : x;  // string
}

function test2(x: Maybe<number>) {
    let x1 = getOrElse(x, -1);         // number
    let x2 = isDefined(x) ? x : -1;    // number
    let x3 = isUndefined(x) ? -1 : x;  // number
}

使用 --outFile 合并 AMDSystem 模塊

在使用 --module amd 或者 --module system 的同時(shí)制定 --outFile 將會(huì)把所有參與編譯的模塊合并為單個(gè)包括了多個(gè)模塊閉包的輸出文件.

每一個(gè)模塊都會(huì)根據(jù)其相對(duì)于 rootDir 的位置被計(jì)算出自己的模塊名稱.

例子

// 文件 src/a.ts
import * as B from "./lib/b";
export function createA() {
    return B.createB();
}
// 文件 src/lib/b.ts
export function createB() {
    return { };
}

結(jié)果為:

define("lib/b", ["require", "exports"], function (require, exports) {
    "use strict";
    function createB() {
        return {};
    }
    exports.createB = createB;
});
define("a", ["require", "exports", "lib/b"], function (require, exports, B) {
    "use strict";
    function createA() {
        return B.createB();
    }
    exports.createA = createA;
});

支持 SystemJS 使用 default 導(dǎo)入

像 SystemJS 這樣的模塊加載器將 CommonJS 模塊做了包裝并暴露為 default ES6 導(dǎo)入項(xiàng). 這使得在 SystemJS 和 CommonJS 的實(shí)現(xiàn)由于不同加載器不同的模塊導(dǎo)出方式不能共享定義.

設(shè)置新的編譯選項(xiàng) --allowSyntheticDefaultImports 指明模塊加載器會(huì)進(jìn)行導(dǎo)入的 .ts.d.ts 中未指定的某種類型的默認(rèn)導(dǎo)入項(xiàng)構(gòu)建. 編譯器會(huì)由此推斷存在一個(gè) default 導(dǎo)出項(xiàng)和整個(gè)模塊自己一致.

此選項(xiàng)在 System 模塊默認(rèn)開啟.

允許循環(huán)中被引用的 let/const

之前這樣會(huì)報(bào)錯(cuò), 現(xiàn)在由 TypeScript 1.8 支持. 循環(huán)中被函數(shù)引用的 let/const 聲明現(xiàn)在會(huì)被輸出為與 let/const 更新語義相符的代碼.

例子

let list = [];
for (let i = 0; i < 5; i++) {
    list.push(() => i);
}

list.forEach(f => console.log(f()));

被編譯為:

var list = [];
var _loop_1 = function(i) {
    list.push(function () { return i; });
};
for (var i = 0; i < 5; i++) {
    _loop_1(i);
}
list.forEach(function (f) { return console.log(f()); });

然后結(jié)果是:

0
1
2
3
4

改進(jìn)的 for..in 語句檢查

過去 for..in 變量的類型被推斷為 any, 這使得編譯器忽略了 for..in 語句內(nèi)的一些不合法的使用.

從 TypeScript 1.8 開始:

  • for..in 語句中的變量隱含類型為 string.
  • 當(dāng)一個(gè)有數(shù)字索引簽名對(duì)應(yīng)類型 T (比如一個(gè)數(shù)組) 的對(duì)象被一個(gè) for..in 索引數(shù)字索引簽名并且沒有字符串索引簽名 (比如還是數(shù)組) 的對(duì)象的變量索引, 產(chǎn)生的值的類型為 T.

例子

var a: MyObject[];
for (var x in a) {   // x 的隱含類型為 string
    var obj = a[x];  // obj 的類型為 MyObject
}

模塊現(xiàn)在輸出時(shí)會(huì)加上 "use strict;"

對(duì)于 ES6 來說模塊始終以嚴(yán)格模式被解析, 但這一點(diǎn)過去對(duì)于非 ES6 目標(biāo)在生成的代碼中并沒有遵循. 從 TypeScript 1.8 開始, 輸出的模塊總會(huì)為嚴(yán)格模式. 由于多數(shù)嚴(yán)格模式下的錯(cuò)誤也是 TS 編譯時(shí)的錯(cuò)誤, 多數(shù)代碼并不會(huì)有可見的改動(dòng), 但是這也意味著有一些東西可能在運(yùn)行時(shí)沒有征兆地失敗, 比如賦值給 NaN 現(xiàn)在會(huì)有運(yùn)行時(shí)錯(cuò)誤. 你可以參考這篇 MDN 上的文章 查看詳細(xì)的嚴(yán)格模式與非嚴(yán)格模式的區(qū)別列表.

使用 --allowJs 加入 .js 文件

經(jīng)常在項(xiàng)目中會(huì)有外部的非 TypeScript 編寫的源文件. 一種方式是將 JS 代碼轉(zhuǎn)換為 TS 代碼, 但這時(shí)又希望將所有 JS 代碼和新的 TS 代碼的輸出一起打包為一個(gè)文件.

.js 文件現(xiàn)在允許作為 tsc 的輸入文件. TypeScript 編譯器會(huì)檢查 .js 輸入文件的語法錯(cuò)誤, 并根據(jù) --target--module 選項(xiàng)輸出對(duì)應(yīng)的代碼. 輸出也會(huì)和其他 .ts 文件一起. .js 文件的 source maps 也會(huì)像 .ts 文件一樣被生成.

使用 --reactNamespace 自定義 JSX 工廠

在使用 --jsx react 的同時(shí)使用 --reactNamespace <JSX 工廠名稱> 可以允許使用一個(gè)不同的 JSX 工廠代替默認(rèn)的 React.

新的工廠名稱會(huì)被用來調(diào)用 createElement__spread 方法.

例子

import {jsxFactory} from "jsxFactory";

var div = <div>Hello JSX!</div>

編譯參數(shù):

tsc --jsx react --reactNamespace jsxFactory --m commonJS

結(jié)果:

"use strict";
var jsxFactory_1 = require("jsxFactory");
var div = jsxFactory_1.jsxFactory.createElement("div", null, "Hello JSX!");

基于 this 的類型收窄

TypeScript 1.8 為類和接口方法擴(kuò)展了用戶定義的類型收窄函數(shù).

this is T 現(xiàn)在是類或接口方法的合法的返回值類型標(biāo)注. 當(dāng)在類型收窄的位置使用時(shí) (比如 if 語句), 函數(shù)調(diào)用表達(dá)式的目標(biāo)對(duì)象的類型會(huì)被收窄為 T.

例子

class FileSystemObject {
    isFile(): this is File { return this instanceof File; }
    isDirectory(): this is Directory { return this instanceof Directory;}
    isNetworked(): this is (Networked & this) { return this.networked; }
    constructor(public path: string, private networked: boolean) {}
}

class File extends FileSystemObject {
    constructor(path: string, public content: string) { super(path, false); }
}
class Directory extends FileSystemObject {
    children: FileSystemObject[];
}
interface Networked {
    host: string;
}

let fso: FileSystemObject = new File("foo/bar.txt", "foo");
if (fso.isFile()) {
    fso.content; // fso 是 File
}
else if (fso.isDirectory()) {
    fso.children; // fso 是 Directory
}
else if (fso.isNetworked()) {
    fso.host; // fso 是 networked
}

官方的 TypeScript NuGet 包

從 TypeScript 1.8 開始, 將為 TypeScript 編譯器 (tsc.exe) 和 MSBuild 整合 (Microsoft.TypeScript.targetsMicrosoft.TypeScript.Tasks.dll) 提供官方的 NuGet 包.

穩(wěn)定版本可以在這里下載:

與此同時(shí), 和每日 npm 包對(duì)應(yīng)的每日 NuGet 包可以在 https://myget.org 下載:

tsc 錯(cuò)誤信息更美觀

我們理解大量單色的輸出并不直觀. 顏色可以幫助識(shí)別信息的始末, 這些視覺上的線索在處理復(fù)雜的錯(cuò)誤信息時(shí)非常重要.

通過傳遞 --pretty 命令行選項(xiàng), TypeScript 會(huì)給出更豐富的輸出, 包含錯(cuò)誤發(fā)生的上下文.

展示在 ConEmu 中美化之后的錯(cuò)誤信息

高亮 VS 2015 中的 JSX 代碼

在 TypeScript 1.8 中, JSX 標(biāo)簽現(xiàn)在可以在 Visual Studio 2015 中被分別和高亮.

jsx

通過 工具->選項(xiàng)->環(huán)境->字體與顏色 頁面在 VB XML 顏色和字體設(shè)置中還可以進(jìn)一步改變字體和顏色來自定義.

--project (-p) 選項(xiàng)現(xiàn)在接受任意文件路徑

--project 命令行選項(xiàng)過去只接受包含了 tsconfig.json 文件的文件夾. 考慮到不同的構(gòu)建場景, 應(yīng)該允許 --project 指向任何兼容的 JSON 文件. 比如說, 一個(gè)用戶可能會(huì)希望為 Node 5 編譯 CommonJS 的 ES 2015, 為瀏覽器編譯 AMD 的 ES5. 現(xiàn)在少了這項(xiàng)限制, 用戶可以更容易地直接使用 tsc 管理不同的構(gòu)建目標(biāo), 無需再通過一些奇怪的方式, 比如將多個(gè) tsconfig.json 文件放在不同的目錄中.

如果參數(shù)是一個(gè)路徑, 行為保持不變 - 編譯器會(huì)嘗試在該目錄下尋找名為 tsconfig.json 的文件.

允許 tsconfig.json 中的注釋

為配置添加文檔是很棒的! tsconfig.json 現(xiàn)在支持單行和多行注釋.

{
    "compilerOptions": {
        "target": "ES2015", // 跑在 node v5 上, 呀!
        "sourceMap": true   // 讓調(diào)試輕松一些
    },
    /*
     * 排除的文件
     */
    "exclude": [
        "file.d.ts"
    ]
}

支持輸出到 IPC 驅(qū)動(dòng)的文件

TypeScript 1.8 允許用戶將 --outFile 參數(shù)和一些特殊的文件系統(tǒng)對(duì)象一起使用, 比如命名的管道 (pipe), 設(shè)備 (devices) 等.

舉個(gè)例子, 在很多與 Unix 相似的系統(tǒng)上, 標(biāo)準(zhǔn)輸出流可以通過文件 /dev/stdout 訪問.

tsc foo.ts --outFile /dev/stdout

這一特性也允許輸出給其他命令.

比如說, 我們可以輸出生成的 JavaScript 給一個(gè)像 pretty-js 這樣的格式美化工具:

tsc foo.ts --outFile /dev/stdout | pretty-js

改進(jìn)了 Visual Studio 2015 中對(duì) tsconfig.json 的支持

TypeScript 1.8 允許在任何種類的項(xiàng)目中使用 tsconfig.json 文件. 包括 ASP.NET v4 項(xiàng)目, 控制臺(tái)應(yīng)用, 以及 用 TypeScript 開發(fā)的 HTML 應(yīng)用. 與此同時(shí), 你可以添加不止一個(gè) tsconfig.json 文件, 其中每一個(gè)都會(huì)作為項(xiàng)目的一部分被構(gòu)建. 這使得你可以在不使用多個(gè)不同項(xiàng)目的情況下為應(yīng)用的不同部分使用不同的配置.

展示 Visual Studio 中的 tsconfig.json

當(dāng)項(xiàng)目中添加了 tsconfig.json 文件時(shí), 我們還禁用了項(xiàng)目屬性頁面. 也就是說所有配置的改變必須在 tsconfig.json 文件中進(jìn)行.

一些限制

  • 如果你添加了一個(gè) tsconfig.json 文件, 不在其上下文中的 TypeScript 文件不會(huì)被編譯.
  • Apache Cordova 應(yīng)用依然有單個(gè) tsconfig.json 文件的限制, 而這個(gè)文件必須在根目錄或者 scripts 文件夾.
  • 多數(shù)項(xiàng)目類型中都沒有 tsconfig.json 的模板.