### 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(); // error
Project.Core.FunB(); // OK
Project.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.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。