js是动态类型的,ts是静态类型的。在大型项目中,变量没有类型,若出现bug很难去查找错误,变得很难维护。因此,ts语言越来越受前端程序员的欢迎。
1.类型声明
- 类型声明是TS非常重要的一个特点
- 通过类型声明可以指定TS中变量 (参数、形参) 的类型
- 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错。简而言之,类型声明给变是设置了类型,使得变量只能存储某种类型的值
语法:
let 变量: 类型;
let 变量: 类型 = 值;
function fn(参数: 类型,参数: 类型): 类型{
}
如下所示,在ts文件中可以用js的方式写代码,这是兼容的。
若给变量限定类型,再赋值时可以提供报错信息。
若变量声明时被赋值,即使未显示声明类型,ts文件也可以自动推导变量类型
在函数中若不限定参数类型则容易报错
在函数中给参数限定类型,可以提示报错信息。
1.1 number、string、boolean
let a:number =10
let b:string = "hello"
let c:boolean = true
1.2 字面量
字面量取值只能取预设的值,不能赋值其它的。
//可使用 | 连接多个类型(联合类型)
let b : "male" | "female"
b = "male"
b= "female"
//变量只能是string 或 boolean类型
let c : string | boolean
c = "hello"
c = true
1.3 any
any代表任意类型,意味着ts关闭了类型检测。
ts中,不建议使用any
let a:any
a = 11
a = "hello"
a = true
//any类型变量可以赋值给其它变量
let b:string
b = a
1.4 unknown
unknown类型可以赋值任何值,但是赋值给其它变量时会报错。
unknown其实就是类型安全的any类型。
let a:unknown
a = 11
a = "hello"
a = true
//unknown类型赋值给其它变量时会报错。
let b:string
a = "hello"
b = a //报错,即使变量a被赋值了字符串类型
//若想将unknown类型赋值给其它变量,需要先进行类型检测。
if(typeof a === "string") {
b= a
}
//或者进行类型断言
b = a as string
b = <string>a
/**
* 语法 : 变量 as 类型 或者 <类型>变量
*/
1.5 void
void 用来标记函数没有返回值
function fn():void {
}
function fn1():void {
return;
}
function fn2():void {
return null;
}
function fn1():void {
return undefined;
}
1.6 never
never表示永远不会返回结果
function fn():never{
throw new Error("错误");
}
1.7 object
object表示一个js对象,可以在{}里限定对象的属性。
语法:{属性名:属性值}
//object表示一个js对象
let a:object
a = {}
a = function(){}
//但是js里一切皆对象,所以这个不实用,在对象里我们更想限制对象里的属性
let b:{name:string}
b = {name:"孙悟空"}
// 属性可选的表示方法,属性名后面加?
let c:{name:string,age?:number}
c = {name:"张三"}
c = {name:"张三",age:18}
//之前的标识方法是属性必须完全符合标准才行,若表示属性至少有一个,其他不做限制的表示方法如下:
//可以在后面加上数组标识,属性名一般是字符串类型,可以用任意字符串表示,属性值可以用any类型
let d:{name:string,[propName:string]:any}
d = {name:"李四",a:1,b:2,c:3}
js里函数也是对象,因此可以用如下的方式限定类型
//可以限制函数的参数类型和返回值类型
let e:(a:number,b:number)=>number
e = function(n1:number,n2:number):number{
return n1+n2
}
1.8 array
数组的类型声明:
类型[]
Array<类型>
//string[]表示字符串类型数组
let a:string[]
a= ["a","b","c"]
//number[]表示数值类型数组
let b:number[]
b=[4,5,6]
//Array<类型>是另一种表示方法
let c :Array<number>
c = [7,8,9]
1.9 tuple 元祖
元祖就是固定长度的数组。
语法:[类型,类型]
let a:[string,string]
a = ["hello","world"]
let b:[string,number]
b = ["hello",123]
1.10 enum 枚举
enum Gender {
Male,
Female
}
let a = {name:"孙悟空",gender:Gender.Male}
console.log(a.gender === Gender.Male)
1.11 类型的其他用法
// 用 | 表示类型或
let a:string| number
// 用 & 表示类型且
let b:{name:string} & {age : number}
//类型别名
type myType = 1|2|3|4|5
let c:myType //等价于 let c:1|2|3|4|5
2.编译选项
如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件。
tsc xxx.ts -w
2.1 tsconfig.json文件配置
如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件。
tsconflg.son是一个SON文件,添加配晋文件后,只需只需 tsc 命令即可亮成对整个项目的编译
2.1.1 include
定义希望被编译文件所在的目录.
{
"include" :["src/**/*","tests/**/*"]
}
上述示例中,所有src目录和tests目录下的文件都会被编译
2.1.2 exclude
定义需要排除在外的目录
{
"exclude":["node_modules/**/*"]
}
在上述的目录下的文件不会被编译。
2.1.3 extends
定义被继承的配置文件
{
"extends":"./configs/base"
}
在上述示例中,当前配置文件会自动包含config目录下base.json中的所有配置信息
2.1.4 files
制定被编译文件的列表,只有需要编译的文件少时才会用到
{
"files": [
"core.ts",
"sys.ts",
"types.ts"
]
}
2.2 compilerOptions (编译选项)
2.2.1 target
制定编译TS为ES的版本
//'es3','es5','es6','es2015 ,es2016 ,s2017 ,es2018 ,es2019'es2020
{
"compilerOptions":{
"target":"ES6"
}
}
2.2.2 module
指定要使用的模块化的规范
// 'node','commonjs',amd','system', 'umd',es6','es2015','es2020','esnext
{
"compilerOptions":{
"target":"ES6",
"module":"es2015"
}
}
2.2.3 lib
指定项目中要使用的库
{
"compilerOptions":{
"target":"ES6",
"module":"es2015",
"lib": ["ES6","dom"]
}
}
2.2.4 outDir
用来指定编译后文件所在的目录
{
"compilerOptions":{
"target":"ES6",
"module":"es2015",
"lib": ["ES6","dom"],
"outDir": "./dist"
}
}
2.2.5 outFile
将编译后的文件合并成一个文件。
{
"compilerOptions":{
"target":"ES6",
"module":"es2015",
"lib": ["ES6","dom"],
"outDir": "./dist",
"outFile": "./dist/app.js"
}
}
注意只能合成全局作用域的文件。
当为模块化文件时,module必须选择“amd”或“system”才能合成一个文件
2.2.6 allowJs
是否对js文件进行编译,默认是false
若应用某些模块是js写的,则需要把js也编译过去
{
"compilerOptions":{
"allowJs":true,
}
}
2.2.7 checkJs
检查js代码是否复合语法规范,默认是false
{
"compilerOptions":{
"checkJs":true,
}
}
2.2.8 removeComments
编译后是否移除注释
{
"compilerOptions":{
"removeComments":true,
}
}
2.2.9 noEmit
不生成编译后的文件。
当想用TS检查语法时,不希望生成编译后的文件可以开启。
{
"compilerOptions":{
"noEmit":true,
}
}
2.2.10 noEmitError
当有错误时不生成编译后的文件。
{
"compilerOptions":{
"noEmitError":true,
}
}
2.2.11 alwaysStrict
用来设置编译后是否使用严格模式,默认为false
在严格模式下,js性能会更好。
{
"compilerOptions":{
"alwaysStrict":true,
}
}
2.2.12 noImplicitAny
不允许隐式的any类型
{
"compilerOptions":{
"noImplicityAny":true,
}
}
2.2.13 noImplicitThis
不允许不明确类型的this
{
"compilerOptions":{
"noImplicityAny":true,
}
}
2.2.14 strictNullChecks
严格的检查控制
{
"compilerOptions":{
"strictNullChecks":true,
}
}
2.2.15 strict
所有严格检查的总开关
{
"compilerOptions":{
"strict":true,
}
}
3.类和对象
定义类
class 类名 {
属性名: 类型;
constructor(参数:类型){
this.属性名 = 参数;
}
方法名(){
...
}
}
示例:
class Person{
name:string;
age:number;
constructor(name:string,age:number){
this.name = name;
this.age = age;
}
sayHello(){
console.log("Hello");
}
}
类似于java,在属性名称前加static可将属性改为类属性或类方法。
加readonly可将属性变为只读
class Person {
name = "张三";
static address = "北京市";
readonly card = 123456;
}
const per = new Person();
console.log(per.name); //张三
console.log(Person.address); // 北京市
per.card = 123457 //报错,只读属性不能被修改
console.log(per.card);