tsconfig.json常用配置
选项一:配置编译目录(rootDir)和输出目录(outDir)
- 一般来讲在根目录下创建src目录(存放ts代码)和dist目录(存放编译后的js代码)
- 在tsconfig目录下创建
rootDir": "./src" outDir": "./dist"
选项二:配置target选项
- 指定js编译后的版本是多少
理解:
通过配置选择编译后的版本,如果是大于或等于2016(如:es2016)那么使用ES6语法会转换为es6的形式,如果为(es5)则会将代码转化那位es5的格式通常指的是使用es6的语法
class Student { name!: string constructor() { this.name = 'wanggu' } }
"use strict"; var Student = /** @class */ (function () { function Student() { this.name = 'wanggu'; } return Student; }());
"use strict"; class Student { constructor() { this.name = 'wanggu'; } }
选项三、module选择
- 可以理解为一种规范,有多种选项可以选择
理解:
一般情况,保持原有配置就行,即(commonjs)
选线三、配置lib选项
- lib选项表示问价需要的库文件一般配置
DOM
和es2016
配合使用
"lib": [ "DOM", "es2016" ]
理解
在使用ES6的语法时,由于默认识别的时ES5所以无法识别,这是就需要引入支持ES6的库即可,如果不引入而使用es6的语法可能就会出现这样的报错
选项四、配置strict
选项
strict
选项选择为true
表示启用所有严格的类型检查选项,一般情况建议打开,对代码的规范性有帮助,特殊需求可以关闭然后按需加载"strict": true,
选项五、配置declaration选项
- 表示声明文件的开始状态
理解:
当开启此选项时,我们编写的ts文件就需要导出了,否则在生成的文件中就为一个空对象
选项六、配置removeComments选项
- 编译后的js文件不含注释.
类型注解与类型判断.
// 类型注解 let presice: number = 3 type StudentType = { name: string age: number } let stuObj: StudentType = { name: 'wangwu', age: 18, } // 类型推导 /** * 当不加类型注解时会在首次赋值时分析类型,如果后面使用时类型与初次定义类型时不符和,则报错 */ let count = 3 let stuObj2 = { name: 'wangwu', age: 18, }
any和unknown的区别
- 相同点:
都可以作为其他类型的父类 - 不同点
前者可以作为其他类型的子类,而unknown不可以;如果定义对象,any可访问对象内的属性,unknown不可以,并且都没有类型推断()
let sname: any = 'xiaoming' let sname2 = 1 let sname3: number = 1 let obj1: any = { username: 'wangwu', age: 20 } obj1.username = 'zhangsan' let obj2: unknown = { username: 'wangwu', age: 20 } obj2.username = 'zhangsan' //此处报错,obj2的类型未知 let str: unknown = 'xiaowang' let str2 = str str2 = 1 console.log(typeof sname2) //number console.log(1223)
函数和函数类型
//函数式写法 function info(name: string, age: number): object { //object表示返回值类型,如果不加会自动推断 console.log('name:' + name, 'age:' + age) return {} } // info('wangwu', 20) // 函数表达式写法 let fun = function (name: string, age: number) { console.log('name:' + name, 'age:' + age) return {} } // 函数表达式的高级写法 let fun2: (name: string, age: number) => number = function ( name: string, age: number ) { console.log('name:' + name, 'age:' + age) return 1 } // 函数表达式的高级写法虽然更规范,但是太长,如果参数较多,则不方便 //所以可以将参数类型抽离出来 type TypeInfoFun = (name: string, age: number) => number let infofun: TypeInfoFun = function (name, age) { console.log(name, age) return 3 } infofun('wangwu', 23) // rest 参数 function infoRest(name: string, age: number, ...rest: any): object { console.log('name:' + name, 'age:' + age) return rest } infoRest('wangwu', 20, '111', 23) //rest的存在时改写法不会报错
函数类型升级
type TyStuObj = { username?: string age?: number phone?: string } // function info(stuObj: TyStuObj) { // console.log('name:' + stuObj.username, 'age:' + stuObj.age) // return 3 // } // let stuobj: TyStuObj = { username: 'John', age: 20, phone: '123456' } // info(stuobj) // 函数结构 /* 在定义结构对象的时候选择 ?: 的形式表示非必须可选 */ function subInfo({ username, phone }: TyStuObj) { console.log('name:' + username, 'age:' + phone) return 3 } subInfo({ username: 'xiaoming', phone: '20' })
BigInt方法
// const max = Number.MAX_SAFE_INTEGER // console.log(max) // const maxBigOne = max + 1 // console.log(maxBigOne) // const maxBigTwo = max + 2 // console.log(maxBigTwo) // console.log(maxBigOne === maxBigTwo) //true // 需要将lib库配置为es2020因为BigInt实在es2020后才出现 // const max = BigInt(Number.MAX_SAFE_INTEGER) // console.log(max) // const maxBigOne = max + BigInt(1) // console.log(maxBigOne) // const maxBigTwo = max + BigInt(2) // console.log(maxBigTwo) // console.log(maxBigOne === maxBigTwo) //false // 简写 需要将target配置为es2020 // const max = BigInt(Number.MAX_SAFE_INTEGER) // console.log(max) // const maxBigOne = max + 1n // console.log(maxBigOne) // const maxBigTwo = max + 2n // console.log(maxBigTwo) // console.log(maxBigOne === maxBigTwo) //false
枚举
什么情况下never被直接使用
// dataFlowAnalysisWithNever 方法穷尽了 DataFlow的所有可能类型 //使用never避免出现未来扩展新的类没有的数据类型的实现,目的就是写出类型绝对俺去那的代码 type DadaFlow = string | number function dataFlowAnalysisWithNever(dataFlow: DadaFlow) { if (typeof dataFlow === 'string') { console.log('字符串类型') } else if (typeof dataFlow === 'number') { console.log('数值类型') } else { let data = dataFlow } } dataFlowAnalysisWithNever('免税店') dataFlowAnalysisWithNever(3)
枚举使用
- 枚举的定义:
用来存放一组固定的常 - 枚举分类
数字枚举
字符串枚举 - 取值
枚举的定义可以理解为一个对象,通过对象访问属性的方法可以访问到对应的值 - 枚举底层
数字枚举为双向映射,而字符串枚举为单项映射
// 数字枚举 /** * 无需给每个变量赋值,只需给第一个赋值后面会依次递增 */ enum Week { Monday = 1, Tuesday, Wensday, ThirsDay, Firday, Sarturday, Sunday, } console.log(Week.Monday) //1 console.log(Week['Wensday']) //3 console.log(Week[1]) //Monday console.log(Week[3]) //Tuesday // 字符串枚举 enum WeekStr { Monday = 'Monday', Tuesday = 'Tuesday', Wensday = 'Wensday', ThirsDay = 'ThirsDay', Firday = 'Firday', Sarturday = 'Sarturday', Sunday = 'Sunday', } console.log(WeekStr.Monday) console.log(WeekStr['Monday'])
"use strict"; var Week; (function (Week) { Week[Week["Monday"] = 1] = "Monday"; Week[Week["Tuesday"] = 2] = "Tuesday"; Week[Week["Wensday"] = 3] = "Wensday"; Week[Week["ThirsDay"] = 4] = "ThirsDay"; Week[Week["Firday"] = 5] = "Firday"; Week[Week["Sarturday"] = 6] = "Sarturday"; Week[Week["Sunday"] = 7] = "Sunday"; })(Week || (Week = {})); console.log(Week.Monday); console.log(Week['Wensday']); console.log(Week[1]); console.log(Week[3]); var WeekStr; (function (WeekStr) { WeekStr["Monday"] = "Monday"; WeekStr["Tuesday"] = "Tuesday"; WeekStr["Wensday"] = "Wensday"; WeekStr["ThirsDay"] = "ThirsDay"; WeekStr["Firday"] = "Firday"; WeekStr["Sarturday"] = "Sarturday"; WeekStr["Sunday"] = "Sunday"; })(WeekStr || (WeekStr = {})); console.log(WeekStr.Monday); console.log(WeekStr['Monday']);
枚举的好处
- 有默认值和可以自增值,节省编码时间
- 语义更加清晰,可读性增强
- 因为枚举是一种值类型的数据类型,方法参数可以明确参数类型为枚举类型
元组
定义:
符合下面条件的数据就是元组
1、定义是的元素额的类型确定,但各个元素的类型不必相同
2、为元素赋值时,该值必须时当前未知的类型
let salary: [string, number, number, string] = ['王五', 8000, 1000, 'ok'] // 取值 console.log(salary[1])
接口(interface)定义,实现,场景应用
定义
是为一些类同类对象或同类别的类提供属性定义和方法声明但没有任何赋值和实现的数据类型
接口实现
应用场景
1、提供方法的兑现类型的参数时使用
2、为多个同类别的类提供统一的方法和属性声明
interface Produce { id: number name: string price: number count: number } function caklTotal(produce: Produce) { console.log(produce) console.log(produce.price) } caklTotal({ id: 100, name: 'test', price: 100, count: 200 })
联合类型(Union Type)
定义:多个类型的合并类型
// 1、基本数据类型的联合类型 // 指多个类型的合并类型 function add(previous: string | number, current: string | number) {} // 2、引用类型的联合类型 interface Car { brand: string No: number price: number placeOrigin: string load(): void } interface Plane { categroy: string price: number placeOrigin: string airline: string load(): void } function carry(vachile: Car | Plane) { // 当用形参访问的时候只能够找到公共的属性 }
使用type定义类型
type和接口类似,都是用来定义类型,但type和interface的区别如下:
区别一:定义类型的范围不同
interface只能定义对象类型或接口当名字的函数类型
type可以定义任何类型,包括基础类型、联合类型、交叉类型、元组。
区别2:接口可以exdents一个或者多个继承类,也可以继承type,但type类型没有继承功能,但一般接口继承类和ytpe的应用常见很少见
区别3:用type交叉类型&可让类型中的成员合并
区别4、皆接口可以合并声明
定义两个相同名称的接口会合并声明,定两个同名的type会出现编译错误
一种特殊的接口类型
接口当名字的函数类型
// vuex4 interface ActionContext { (state: any, commit: any): void } let actionContext: ActionContext = (state: any, commit: any): void => { console.log(state) } actionContext('abc', 'df') //abc
一个联合类型技巧性的使用场景
当在使用联合类型时当以固定的值时就以这个值为类型
type IncreaseBoolean = Boolean | 1 | 0 function mounted(isStrtUp: IncreaseBoolean) { if (isStrtUp) { console.log('yes') } else { console.log('no') } } mounted(1) //yes mounted(0) //no
声明文件
描述:在ts文件里引用js文件
实现:需要在tsconfig.json配置"allowJs": true,
举例:
export let price = 3;
import { price } from './17prouduce.js' console.log(price)
为什么要使用声明文件
如果文件使用TS编写,在编译时会自动生成声明文件,并在发布的时候讲.d.ts文件一起发布,无需编写声明文件;
当在TS文件中使用第三方库的类型或使用集成库时,比如使用:@types/jquery库,ES库的Map类型,这些库用JS开发,不能获取TS一样的类型提示,需要一个声明文件来帮助库的使用者获取库的类型提示。
注意:声明文件中只对类型定义,不能进行赋值和实现