TypeScript入门 (Google开发者大会Angular部分内容整理)

为什么要使用TypeScript(演讲者的观点,有些我并不认同)

  • 编写很大的JavaScript应用往往不是那么容易

JavaScript程序往往在很大型的应用中组织起来会遇到很多麻烦。

  • 只有JavaScript是不够的

JavaScript没有类型检查。

  • JavaScript版本众多且混乱

现在的JavaScript出现了ES5、ES6、ES7并行的情况,很难抉择。

TypeScript是什么

  • TypeScript是JavaScript的一个类型超集,它会编译为纯JavaScript。

TypeScript和JavaScript的关系

  • 它是开源的,且支持任何浏览器,任何主机和任何操作系统。

TypeScript的优势

  • 编译时类型检查
  • 使用“allowJs”消耗JavaScript文件(?)
  • 选择渐进式系统
  • 可以立即使用未来的JavaScript功能(ES6、ES7)

例子

代码主要功能:传入一些邮件地址,并对邮件地址进行一些检查。

Object.defineProperty(window, "MySweetApp", { value: "v1.0.0", readonly: false });

function deliveryMethod() {
    // TODO
    return "overnight";
}

function shipWeight(){
    return parseInt(document.getElementById('weight'));
}

/*
 * @param {(string | string[])} emailAddr - An email address of array of email addresses
 */
function sendUpdates(emailAddr) {
    function sendEmail(addr){
        // Default to standard delivery if empty
        console.log(`Shipping to ${addr} via ${deliveryMethod() | "standard"} delivery`);

        if (shipWeight > 100){
            console.log("WARNING: Oversize package");
        }
    }
    // If it's an array, loop over it
    if (emailAddr.length) {
        emailAddr.forEach((idx, val) => {
            sendEmail(val.trim());
        });
    } else {
        sendEmail(emailAddr.trim());
    }
}

这段JavaScript在以.js结尾时不会报任何错误,但当我们将文件名改成.ts之后会发现很多报错。
让我们逐一改掉它们。

readonly不存在在类型PropertyDescriptor之中,此处应该为writable: true

我们不能用>比较function和数字,此处应该为if (shipWeight() > 100)

document.getElementById('weight')不是一个String类型,很可能无法parseInt,我们在后面加上.innerText


在不确定左边对象类型的前提下位运算不一定能进行,在这里明显是把“||”写成了“|

TypeScript可以为参数声明数据类型,让我们为function sendUpdates(emailAddr)中的emailAddr增加数据类型string | string[]
然后发现又多了两处报错:


forEach不支持String类型。


trim不支持String[]类型,那么我们需要在这个地方增加类型判断。将if (emailAddr.length)修改为if (Array.isArray(emailAddr))

这时候发现又多出来一个错误


trim()不支持Number类型,原来是写错了forEach中参数的位置。将emailAddr.forEach((idx, val)改为emailAddr.forEach((val, idx)
改正后的代码

Object.defineProperty(window, "MySweetApp", {
    value: "v1.0.0",
    writable: false
});

function deliveryMethod() {
    // TODO
    return "overnight";
}

function shipWeight() {
    return parseInt(document.getElementById('weight').innerText);
}

/*
 * @param {(string | string[])} emailAddr - An email address of array of email addresses
 */
function sendUpdates(emailAddr : String | String[]) {
    function sendEmail(addr) {
        // Default to standard delivery if empty
        console.log(`Shipping to ${addr} via ${deliveryMethod() || "standard"} delivery`);

        if (shipWeight() > 100) {
            console.log("WARNING: Oversize package");
        }
    }
    // If it's an array, loop over it
    if (Array.isArray(emailAddr)) {
        emailAddr.forEach((val, idx) => {
            sendEmail(val.trim());
        });
    } else {
        sendEmail(emailAddr.trim());
    }
}

JavaScript IS TypeScript

TypeScript的出发点事让JavaScript有更良好的体验,你所知道的JavaScript知识完全可以运用到TypeScript中

实时类型检查

  • 管理JavaScript中最容易出错的可空类型
  • 不可空类型提供“null/undefined”检查

实时类型检查可以很大程度上避免JavaScript中常见的undefined错误。

示例

猜一下代码的每一个分支中的s是什么类型

function test(s : string | string[] | null | undefined) {
    if (s) {
        s; //1
    } else {
        s; //2
    }
    if (s == undefined) {
        s; //3
    } else {
        s; //4
    }
}

第一个if中判断了s是真值,类型可能是String|String[]


else中不是String|String[]那是不是就是null | undefined

添加第三方TypeScript

  • 绝大多数流行的库都有.d.ts类型定义文件
  • 2.0开始不需要任何第三方工具,只需要npm
 npm install -S @types/lodash

TypeScript编辑器支持

总结

  • 使用TypeScript比以前更容易
  • TypeScript和Angular搭配使用体验很棒
  • TypeScript充满未来
Comments
Write a Comment