### 1. typescript 介绍
typeScript是javascript的一个超集, 它遵循最新的es6脚本语言标准,ts扩大了js语法, 曾经存在的js程序能够不通过任何改变的状况下在ts里运行.
长处
- 编译时的强类型: ts设计了一套类型机制来保障编译时的强类型判断.例如你能够申明变量的类型, 那么任何其余类型的赋值将会引起编译谬误
- 模块化: 利用ts的关键词module,能够达到命名空间的成果.而export能够管制是否被内部拜访
module Project { export module Core { function FunA(){}; export function FunB() { FunA() } }}module Project.Core { export function FunC() { FunA(); // error FunB(); // ok }}Project.Core.FunA(); // errorProject.Core.FunB(); // OKProject.Core.FunC(); // OK
- 语法糖: TypeScript能够实现类,接口,枚举,泛型,办法重载等,用简洁的语法丰盛了JavaScript的应用。
环境搭建
mac 环境 node => v10.0.0
全局装置 npm install -g typeScript
命令执行tsc -v 查看版本
应用vscode 配置主动编译
在我的项目下新建tsconfig.json配置文件
新建app.ts
在命令行中执行 tsc app.js
抉择运行工作
抉择tsconfig.json监督
根底
原始数据类型
javascript的类型分为两种: 原始数据类型和对象类型
原始数据类型包含: boolean, number, string null undefined以及es6新定义的symbol
boolean
布尔值是最根底的数据类型, 在ts中应用boolean定义布尔值类型:
let isDone: boolean = false;
留神应用构造函数Boolean发明的对象不是布尔值
let createdByNew: Boolean = new Boolean(1)// var creatednew = new Boolean(1);
在ts中, boolean是js的根本数据类型, 而Boolean是js中的构造函数.
数值number
应用number定义数值类型
let decliter: number = 6;let binary: number = 0b1010;let notANumber: number = NaN;let infinityNumber: number = Infinity;//编译后 var decliter = 6;var binary = 10;var notANumber = NaN;var infinityNumber = Infinity;
字符串
应用string定义字符串类型
// 字符串let myName: string = 'Tom';let myAge: number = 25;// 模板字符串let sentence: string = `hello, my name is name is ${myName}. `// 编译后// 字符串var myName = 'Tom';var myAge = 25;// 模板字符串var sentence = "hello, my name is name is " + myName + ". ";
空值
js中没有空值Void的概念. 在ts中能够用void示意没有任何返回值的函数
function alertName(): void { alert('1111')}// 编译后function alertName() { alert('1111');}
申明一个void类型的变量没有什么用,因为只能将它赋值为undefined和null
Null和Undefined
在ts中.能够应用null和undefined来定义这两个原始数据类型
let u: undefined = undefined;let n: null = null;// 编译后var u = undefined;var n = null;
与void的区别是, undefined和null是所有类型的子类型.也就是说undefined类型的变量.能够赋值给number类型的变量
let num: number = undefined;let u2: undefined;let num2: number = u2;// 编译后var num = undefined;var u2;var num2 = u2;
而void类型的变量不能赋值给number类型的变量
let u3: void;let num3: number = u3;// 报错 Type 'void' is not assignable to type 'number'
任意值
任意值Any用来示意容许赋值为任意类型
什么是任意值类型
如果是一个一般类型. 在赋值过程中扭转类型是不被容许的
let myFavorite: string = 'seven';myFavorite = 7;// 报错 Type 'number' is not assignable to type 'string'.
但如果是any类型. 则容许被赋值为任意类型
let myFavorite: any = 'seven';myFavorite = 7;// 编译后let myFavorite: any = 'seven';myFavorite = 7;
任意值的属性和办法
在任意值上拜访任何属性都是容许的
let anything: any = 'hello';console.log(anything.myname);console.log(anything.myName.firstName);// 编译后var anything = 'hello';console.log(anything.myname);console.log(anything.myName.firstName);
也容许调用任何办法
let anything2: any = 'tom';anything2.setName('jenny');// 编译后var anything2 = 'tom';anything2.setName('jenny');
能够认为申明一个变量为任意值后,对它的任何操作, 返回的内容的类型都是任意值.
未声明类型的变量
变量如果在申明的时候, 未指定其类型, 那么它会被辨认成任意值类型.
let something;something = 'seven';something = 7;// 等价于var something;something = 'seven';something = 7;
弊病
一夜回到解放前. everything is any, ts根本就是js了
查看变量的时候不能疾速晓得类型
ts中的顶级类型 any和unknown
any和unKnown在ts中是所谓的顶级类型
也就是说如果把类型看作是值的汇合时, any和unKnown是所有值的汇合
类型推论
如果没有明确的指定类型, 那么ts会按照类型推论的规定推断出一个类型
什么是类型推论
以下代码尽管没有指定类型, 然而他会在编译的时候报错
let myjfjf = 'seven';myjfjf = 7;// 报错 Type 'number' is not assignable to type 'string'
事实上,它等价于
let myjfjf: string = 'seven';myjfjf = 7;
ts 会在没有明确的指定类型的时候揣测出一个类型, 这就是类型推论
如果定义的时候没有赋值.不论当前有没有赋值, 都会被推断为any类型而齐全不被类型查看
联结类型
联结类型示意取值能够为多种类型中的一种
let jffjjl: string | number;jffjjl = 'seven';jffjjl = 7;// 编译为: var jffjjl;jffjjl = 'seven';jffjjl = 7;let ndnnf: string | number;ndnnf = true;// 报错 Type 'boolean' is not assignable to type 'string | number'.
联结类型应用|分隔每个类型
拜访联结类型的属性或办法
当ts不确定一个联结类型的变量到底是哪个类型的时候, 咱们只能拜访此联结类型的所有类型里共有的属性或者办法
function getLength(someth: number | string): number { return someth.length}// 报错: Property 'length' does not exist on type 'string | number'. Property 'length' does not exist on type 'number'.
示意length属性不是number和string的共有属性, 所以会报错
拜访string和number的共有属性是没问题的
function getLength(someth: number | string): string { return someth.toString();}// 编译后function getLength(someth) { return someth.toString();}
联结类型的变量在被赋值的时候, 会依据类型推论的规定推断出一个类型:
let iuruio: string | number;iuruio = 'seven';console.log(iuruio.length);// 编译失常iuruio = 7;console.log(iuruio.length);// 编译报错
上述例子中第二行的iuruio被推断成了string
而第四行iuruio被推断成了number
对象的类型 - 接口
在ts中, 咱们应用接口interface来定义对象的类型
什么是接口
在面向对象语言中, 接口interface是一个很重要的概念. 它是对行为的形象.
ts中的接口除了可用于对类的一部分行为进行形象以外, 也罕用于对对象的形态进行形容
interface Person { name: string, age: number}let tom: Person = { name: '张三', age: 12}// 编译为var tom = { name: '张三', age: 12};
下面例子中, 定义了一个接口Person,接着定义了一个变量tom, tom的类型是Person,这样咱们就束缚了tom的形态必须和接口Person统一
接口个别首字母大写
定义变量比接口少一些属性是不容许的, 多一些属性也是不容许的
let tom: Person = { name: '张三'} Type '{ name: string; }' is not assignable to type 'Person'.// Property 'age' is missing in type '{ name: string; }'let tom: Person = { name: '张三', age: 12, hhh: '33'}Type '{ name: string; age: number; hhh: string; }' is not assignable to type 'Person'. Object literal may only specify known properties, and 'hhh' does not exist in type 'Person'.
可见赋值的时候, 变量的形态必须和接口保持一致
可选属性
有时候咱们心愿不要齐全匹配一个形态, 能够应用可选属性
interface Person { name: string, age?: number}let tom: Person = { name: '张三'}// 编译为var tom = { name: '张三'};
任意属性
心愿一个接口有任意的属性, 能够应用[propName]
interface Person { name: string, age?: number, [propName: string]: any}let tom: Person = { name: '张三', age: 11, gender: 33, eqweL: 33}// 编译为var tom = { name: '张三', age: 11, gender: 33, eqweL: 33};
须要留神的是: 一旦定义了任意属性, 那么确定属性和可选属性的类型都必须是它的类型的子集
一个接口中只能定义一个任意属性, 如果接口中有多个类型的属性.则能够在任意属性中应用联结类型.
interface Person { name: string, age?: number, [propName: string]: string | number}let tom: Person = { name: '张三', age: 11, gender: 33, eqweL: 33}// 编译为: var tom = { name: '张三', age: 11, gender: 33, eqweL: 33};
只读属性
心愿对象中的一些字段只能在创立时赋值, 能够应用readonly定义只读属性:
interface Person { readonly name: string, age?: number, [propName: string]: string | number}let tom: Person = { name: '张三', age: 11, gender: 33, eqweL: 33}tom.name = '李四';// 报错 Cannot assign to 'name' because it is a read-only property.