9102年,隔壁公司新来的女实习生问我什么是TypeScript ?

clipboard.png

TypeScript不是一个高深的技术,它不过是一个 javascript的超集,那么什么是超集呢?

clipboard.png

所谓的超集 其实就是最终将你写的TypeScript编译成javascript去执行,由于浏览器上能跑的脚本语言是javascript,这个本质要搞清楚javascript

传统的Javascript 缺点:

1.弱类型,不严谨

没法在编写时察觉出同一个变量的类型是否保持一致html

好比:前端

var a = 1 

//若是这个b的值是“1”,字符串
var b = "1"

console.log(a+b)

结果:java

clipboard.png

2.不依赖插件,没法感知编码书写是否出现边际错误(出现某一瞬间空值等)

特别是ES6以前存在全局变量,var会给全局状态下添加属性以及污染全局加上ES5的变量提高做用域等混合状况,很容易致使变量查找时出现undefined的问题,可是这个问题须要代码运行才能报错react

例如:webpack

var a;

    function test() {
        a = 1
    }
    
    console.log(a) //undefined
    console.log(window.a)//undefined
 
    
    -------------------
    
    
    var a;

    function test() {
        a = 1
    }

    test()

     console.log(a)    // 1 
     console.log(window.a) //1
像上面这种状况,若是遇到了,项目很大,排查起来仍是很烦的

3.不依赖插件,没有静态类型以及上下文检查

特别是在书写Node.js的时候,每每这种偏后台类型的代码,高并发场景出现一个小问题都是致命的,若是是一个超大型项目,排查问题起来很是困难es6

传统的javascriptweb

clipboard.png

这段代码,变量a根本就没有定义,可是根本没有报错,这种场景能够在项目中多是右查询没有查询到,而后输出undefined. 但是若是是在使用这个变量去作某些事情typescript

例如: npm

这个a变量是一个用户很核心的数据,可是它是undefined。而后又通过若干的类型转换,被js转换成不知道是什么的数据展现给了客户,那么炸了,可能会引发整个项目出现致命性错误直接奔溃

4. 大型项目,多人合做,若是出了BUG每每可能要浪费你们不少时间(摸鱼时间)

例如 :

你的同事A写了一个模块,大概5个文件,一共1000行代码

通过1000行代码的处理,最终输出好几个值(变量)给了你

以下代码:

export default {
    store,
    checkPassWord,
    applyMiddleWare,
    //....
}

一个不合格的同事 给你的没有注释的代码 因而你 :

clipboard.png

一个合格的同事:

/**
   @params store //数据对象
   @params checkPassWord //检查密码函数
   @params applyMiddleWare //应用中间间

*/
export default {
    store,
    checkPassWord,
    applyMiddleWare,
    //....
}

若是你用到他的暴露对象内容特别多的时候,就要一个一个去看注释,并且关键是:

这里面每一个函数的传入参数,返回的参数,注释不必定那么完整详细。

那么只有去沟通了,一旦沟通起来。时间成本上升,而且若是你们开发任务都特别紧急的时候,炸了~

clipboard.png

因而,TypeScript出现了

TypeScript 3.1 现已发布

最新版本文档地址 最新TypeScript版本文档地址

TypeScript并不能说是一门彻底全新的语言,能够说它是一个基于javaScipt的超集

什么是超集? 其实就是原生ES6语法+Type类型

强烈建议阅读阮一峰老师的 ES6入门

咱们来看下 TypeScript的工做方式:

全局下载TypeScript 手动编译TS文件变成js文件

npm install -g typescript

用全局安装的typescript来编译输出一把刚才的文件

clipboard.png

尚未编译,如今已经开始报出问题,可是报出问题能够继续编译吗?

clipboard.png

即便静态校验出现问题,最终仍是编译成功:

clipboard.png

这里特别注意, TS里面的静态类型,以及枚举等,编译成 js后是不存在的

上面并无体现typeScript的特殊价值

TypeScript的核心原则之一是对值所具备的结构进行类型检查。 它有时被称作“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的做用就是为这些类型命名和为你的代码或第三方代码定义契约。

//接口名为LabelledValue
interface LabelledValue {
  label: string;
}


//函数传入的参数 labelledObj遵循 LabelledValue接口 

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

以上代码通过ts编译后,全部接口和静态类型都没有了 :

function printLabel(labelledObj) {
    console.log(labelledObj.label);
}
var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

若是ts在代码编写阶段出现了类型的校验错误,那么会直接提示:

我将接口的string改为了number类型

clipboard.png

咱们仅仅改变了接口的类型,就马上检验到了错误,这样没必要等到开发模式下的热更新调试后再报错。

固然 你在接口定义时候,能够在变量后加上?

这样是一个可选属性

例如:

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

还有只读属性的接口定义:

interface Point {
    readonly x: number;
    readonly y: number;
}

你能够经过赋值一个对象字面量来构造一个Point。 赋值后, x和y不再能被改变了。

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

用得比较多的函数类型检查

先编写接口

interface SearchFunc {
  (source: string, subString: string): boolean;
}

定义函数

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

对于函数类型的类型检查来讲,函数的参数名不须要与接口里定义的名字相匹配。 好比,咱们使用下面的代码重写上面的例子:

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}

函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的。 若是你不想指定类型,TypeScript的类型系统会推断出参数类型,由于函数直接赋值给了 SearchFunc类型变量。 函数的返回值类型是经过其返回值推断出来的(此例是 false和true)。 若是让这个函数返回数字或字符串,类型检查器会警告咱们函数的返回值类型与 SearchFunc接口中的定义不匹配。

let mySearch: SearchFunc;
mySearch = function(src, sub) {
    let result = src.search(sub);
    return result > -1;
}
鸭式辨形法,说的是:一个动物长得看起来像鸭子,叫起来也像鸭子,那么它就能够被认为是鸭子

定义类的类型:

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

一个接口能够继承多个接口,建立出多个接口的合成接口。

interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface Square extends Shape, PenStroke {
    sideLength: number;
}
照本宣科写了这么多,其实这些就是 TS的最有用的地方。文档写得比较好,建议多去看几遍,前提是必定要学好 ES6

TS中必定要尽可能避免使用any类型

any类型有太多不可预测的后果

function identity<T>(arg: T): T {
    return arg;
}

咱们给identity添加了类型变量T。 T帮助咱们捕获用户传入的类型(好比:number),以后咱们就可使用这个类型。 以后咱们再次使用了 T当作返回值类型。如今咱们能够知道参数类型与返回值类型是相同的了。 这容许咱们跟踪函数里使用的类型的信息。

其余的API能够去刷文档,下面说重点:

工程化环境:

typescript赶上了webpack

React官方推荐使用typescript

clipboard.png

使用传统的 react脚手架

在 Create React App 中使用 TypeScript

npx create-react-app my-app --typescript

typescript赶上webpack

切记 全部的 ts的依赖,都必须是 @types开头的 不然用不了

配置tsconfig.json文件

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ]
}
npm install --save react react-dom @types/react @types/react-dom

webpack.config.js配置文件

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    devtool: "source-map",

    resolve: {
  
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
         
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
};

你们可能对externals字段有所疑惑。 咱们想要避免把全部的React都放到一个文件里,由于会增长编译时间而且浏览器还可以缓存没有发生改变的库文件。

webpack 4.39版配置typeScript

TS最基础关键的核心思想,已经介绍完了

咱们不妨总结一下:

TS最核心的优点 :

静态类型检查+校验,代码并无运行编译,就已经知道哪里有问题了,不管是变量查找仍是类型错误

TS给咱们解决了什么问题

减小了开发沟通成本,打开你的代码就知道传入的是什么参数,返回什么参数。编译后代码量并无增长

TS给咱们带来了什么麻烦

多写了不少接口,类型,一些快速开发的小项目感受用上更麻烦。若是是比较古老的js插件第三方库,还用不了,要另想其余办法去支持。

大型项目,能够上ts,仍是要上ts,中小型项目,看工期,看你是否打算在时间容许状况下尝试使用ts

技术自己没有好坏,长远看,弱类型语言并非那么的友好。谷歌的Go语言,写法就跟TypeScript很像,若是想要拥有更广阔的技术视野,建议前端是能够从TS学起,他们的思想大都差很少。

最后,欢迎你们加入咱们的segmentFault前端交流群,个人我的微信是:CALASFxiaotan,加我会拉你进群哦~

群里大把小姐姐等大家~

clipboard.png

以为写得好,记得点个赞哦,永不脱发
相关文章
相关标签/搜索