一、TypeScript初体验
1. TypeScript 是 JS 的超集,为 JS 添加了类型系统。相比 JS,开发体验 更友好,提前发现错误,Bug更少,增加开发的幸福度。
2. JavaScript 的两个运行环境是什么?1 浏览器 2 Node.js
3. TypeScript 能直接在浏览器或 Node.js 中执行吗?不能
4. 如何将 ts 编译为 js? tsc hello.ts -> hello.js
5. 如何简化执行 ts 代码? ts-node hello.ts
二、基本数据类型
TypeScript 中常用的基本数据类型有 5 个。
1. 分别是:number(数字类型)/ string(字符串类型)/ boolean(布尔类型)/ undefined / null。
2. 重点是:number / string / boolean。
三、TypeScrip(接口和对象类型)
在typescript中,我们定义对象的方式要用关键字interface(接口),我的理解是使用interface来定义一种约束,让数据的结构满足约束的格式。定义方式如下:
//重名interface 可以合并
interface one{name:string}
interface one{age:number}
var x:one={name:'xx',age:20}
//继承
interface one{
name:string
}
interface two extends one{
age:number
}
let obj:two = {
age:18,
name:"string"
}
可选属性 使用?操作符
//可选属性的含义是该属性可以不存在
//所以说这样写也是没问题的
interface Person {
b?:string,
a:string
}
const person:Person = {
a:"213"
}
任意属性 [propName: string]
//在这个例子当中我们看到接口中并没有定义C但是并没有报错
//应为我们定义了[propName: string]: any;
//允许添加新的任意属性
interface Person {
b?:string,
a:string,
[propName: string]: any;
}
const person:Person = {
a:"213",
c:"123"
}
只读属性 readonly
readonly 只读属性是不允许被赋值的只能读取
函数属性
interface Person {
b?: string,
readonly a: string,
[propName: string]: any;
cb():void
}
const person: Person = {
a: "213",
c: "123",
cb:()=>{
console.log(123)
}
}
四、TypeScrip4(数组类型)
//类型加中括号
let arr:number[] = [123]
//这样会报错定义了数字类型出现字符串是不允许的
let arr:number[] = [1,2,3,'1']
//操作方法添加也是不允许的
let arr:number[] = [1,2,3,]
arr.unshift('1')
var arr: number[] = [1, 2, 3]; //数字类型的数组
var arr2: string[] = ["1", "2"]; //字符串类型的数组
var arr3: any[] = [1, "2", true]; //任意类型的数组
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
//表示:只要索引的类型是数字时,那么值的类型必须是数字。
多维数组
let data:number[][] = [[1,2], [3,4]];
any 在数组中的应用
let list: any[] = ['test', 1, [],{a:1}]
五、TypeScrip(类型断言 | 联合类型 | 交叉类型)
联合类型
//例如我们的手机号通常是13XXXXXXX 为数字类型 这时候产品说需要支持座机
//所以我们就可以使用联合类型支持座机字符串
let myPhone: number | string = '010-820'
//这样写是会报错的应为我们的联合类型只有数字和字符串并没有布尔值
let myPhone: number | string = true
tabSelect ( index:Number|string ) :void
交叉类型(多种类型的集合,联合对象将具有所联合类型的所有成员)
interface People {
age: number,
height: number
}
interface Man{
sex: string
}
const xiaoman = (man: People & Man) => {
console.log(man.age)
console.log(man.height)
console.log(man.sex)
}
xiaoman({age: 18,height: 180,sex: 'male'});
断言类型
interface A {
run: string
}
interface B {
build: string
}
const fn = (type: A | B): string => {
return (type as A).run
}
//可以使用类型断言来推断他传入的是A接口的值
临时断言
window.abc = 123
//这样写会报错因为window没有abc这个东西
(window as any).abc = 123
//可以使用any临时断言在 any 类型的变量上,访问任何属性都是允许的。
六、TypeScrip(Class类)
class People{
public name:string
private age:number
protected sex:string
static address:string="河南省郑州市金水区" //static 定义的属性 不可以通过this 去访问 只能通过类名去调用
constructor(name:string,age:number,sex:string){
this.name=name
this.age=age
this.sex=sex
}
run(){
console.log(this.name+"我执行了run函数")
}
// 如果两个函数都是static 静态的是可以通过this互相调用
static runs(){
return console.log('你好啊,static')
}
}
class Man extends People{
constructor(){
super("张三",30,'女')
console.log(this.sex)
}
}
let zhangsan=new People('李四',44,'男')
console.log(zhangsan)
console.log(zhangsan.name)
console.log(People.address)//static 定义的属性 不可以通过this 去访问 只能通过类名去调用
People.runs()//static 定义的属性 不可以通过this 去访问 只能通过类名去调用
zhangsan.run()
let wangwu=new Man()
console.log(wangwu)
console.log(wangwu.name)
wangwu.run()
Man.runs()//static 定义的属性 不可以通过this 去访问 只能通过类名去调用
抽象类
应用场景如果你写的类实例化之后毫无用处此时我可以把他定义为抽象类
或者你也可以把他作为一个基类-> 通过继承一个派生类去实现基类的一些方法
我们在A类定义了 getName 抽象方法但为实现
我们B类实现了A定义的抽象方法 如不实现就不报错 我们定义的抽象方法必须在派生类实现
abstract class A {
name: string
constructor(name: string) {
this.name = name;
}
print(): string {
return this.name
}
abstract getName(): string
}
class B extends A {
constructor() {
super('小满')
}
getName(): string {
return this.name
}
}
let b = new B();
console.log(b.getName());
七、TypeScrip元组类型
元组类型就是数组的变种(元组(Tuple)是固定数量的不同类型的元素的组合)
元组与集合的不同之处在于,元组中的元素类型可以是不同的,而且数量固定。元组的好处在于可以把多个元素作为一个单元传递。如果一个方法需要返回多个值,可以把这多个值作为元组返回,而不需要创建额外的类来表示。
应用场景 例如定义execl返回的数据
let excel: [string, string, number, string][] = [
['title', 'name', 1, '123'],
['title', 'name', 1, '123'],
['title', 'name', 1, '123'],
['title', 'name', 1, '123'],
['title', 'name', 1, '123'],
]
八、tsconfig.json配置文件
"compilerOptions": {
"incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
"tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
"diagnostics": true, // 打印诊断信息
"target": "ES5", // 目标语言的版本
"module": "CommonJS", // 生成代码的模板标准
"outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
"lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
"allowJS": true, // 允许编译器编译JS,JSX文件
"checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
"outDir": "./dist", // 指定输出目录
"rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
"declaration": true, // 生成声明文件,开启后会自动生成声明文件
"declarationDir": "./file", // 指定生成声明文件存放目录
"emitDeclarationOnly": true, // 只生成声明文件,而不会生成js文件
"sourceMap": true, // 生成目标文件的sourceMap文件
"inlineSourceMap": true, // 生成目标文件的inline SourceMap,inline SourceMap会包含在生成的js文件中
"declarationMap": true, // 为声明文件生成sourceMap
"typeRoots": [], // 声明文件目录,默认时node_modules/@types
"types": [], // 加载的声明文件包
"removeComments":true, // 删除注释
"noEmit": true, // 不输出文件,即编译后不会生成任何js文件
"noEmitOnError": true, // 发送错误时不输出任何文件
"noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
"importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
"downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
"strict": true, // 开启所有严格的类型检查
"alwaysStrict": true, // 在代码中注入'use strict'
"noImplicitAny": true, // 不允许隐式的any类型
"strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
"strictFunctionTypes": true, // 不允许函数参数双向协变
"strictPropertyInitialization": true, // 类的实例属性必须初始化
"strictBindCallApply": true, // 严格的bind/call/apply检查
"noImplicitThis": true, // 不允许this有隐式的any类型
"noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
"noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
"noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
"noImplicitReturns": true, //每个分支都会有返回值
"esModuleInterop": true, // 允许export=导出,由import from 导入
"allowUmdGlobalAccess": true, // 允许在模块中全局变量的方式访问umd模块
"moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
"paths": { // 路径映射,相对于baseUrl
// 如使用jq时不想使用默认版本,而需要手动指定版本,可进行如下配置
"jquery": ["node_modules/jquery/dist/jquery.min.js"]
},
"rootDirs": ["src","out"], // 将多个目录放在一个虚拟目录下,用于运行时,即编译后引入文件的位置可能发生变化,这也设置可以虚拟src和out在同一个目录下,不用再去改变路径也不会报错
"listEmittedFiles": true, // 打印输出文件
"listFiles": true// 打印编译的文件(包括引用的声明文件)
}
// 指定一个匹配列表(属于自动指定该路径下的所有ts相关文件)
"include": [
"src/**/*"
],
// 指定一个排除列表(include的反向操作)
"exclude": [
"demo.ts"
],
// 指定哪些文件使用该配置(属于手动一个个指定文件)
"files": [
"demo.ts"
]