TypeScript 由微软开发,是基于 JavaScript 的⼀个扩展语⾔。
TypeScript 包含了 JavaScript 的所有内容,即: TypeScript 是 JavaScript 的超集。
TypeScript 增加了:静态类型检查、接⼝、 泛型等很多现代开发特性,更适合⼤型项⽬ 的开发。
TypeScript 需要编译为 JavaScript ,然后交给浏览器或其他 JavaScript 运⾏环境执⾏
静态类型检查:
在代码运⾏前进⾏检查,发现代码的错误或不合理之处,减⼩运⾏时出现异常的⼏率
这种检查叫静态类型检查,TypeScript 和核⼼就是静态类型检查
同样的功能,TypeScript 的代码量要⼤于 JavaScript,但由于 TypeScript 的代码结构更加 清晰,在后期代码的维护中 TypeScript 却胜于 JavaScript
编译
浏览器不能直接运⾏ TypeScript 代码,需要编译为 JavaScript 再交由浏览器解析器执⾏,TypeScript的文件后缀是.ts
命令行编译
# 全局安装ts,ts安装完之后,会有tsc的命令
npm i typescript -g
# 使用tsc命令编译ts文件,会将对应的ts转换为js文件
tsc test.ts
自动化编译
- 创建编译控制文件
# 创建ts编译控制文件,会在目录生成一个tsconfig.json文件,配置ts到js的转换规则
tsc --init
2.1 监测文件进行编译-该方式无论代码正确还是错误,都会实时转换
# 监测文件-指定文件名会只监测指定文件,实时将ts转换为js
tsc --watch test.ts
# 不指定文件名 则会监测全部ts文件
tsc --watch
# 可以简写为 --w
tsc --w
2.2 监测文件进行变异-该方式只有代码无报错的时候,才会转换
# 方式一: 监测文件-如果语法有报错,则不会编译
tsc --noEmitOnError --watch
// 方式二:tsconfig.json文件中noEmitOnError注释解开,再使用tsc --w
"noEmitOnError": true,
类型声明
使用:对变量、参数进行类型声明
显示声明类型
// 变量声明类型,在赋值的时候如果值与指定类型不符,报类型错误
let a:string
let b:number
let c:boolean
let d:number = 100
a = "1"
b = 2
c = true
// 函数声明形参类型,传参的时候如果类型不符合,报类型错误
function test(a:number,b:string){
console.log(a,b)
}
test(1,"2")
字面量类型
在:后直接写对应的值,对应的字面量就是对应的类型
let a :"hello"
let b:1
// 可以理解为hello和1字面量都是类型,自定义类型,a赋值只能是hello,b赋值只能是1
类型推断
ts根据代码,进行类型推断
let a = 10 // 变量声明同时赋值,赋值是数字,则推断类型是number
a = 20 // 赋值只能是number
数据类型
js类型
- ts中的类型包含所有js的类型, string、number 、boolean 、null 、 undefined 、 bigint 、 symbol 、object
- 其中 object 包含: Array 、 Function 、 Date 、 Error 等类型
新增类型
any
any表示任意类型,变量类型为 any,表示放弃了对该变量的类型检查
let test:any
test = 1
test = "2"
test = false
// any类型的变量,可以赋值给任意类型的变量
let b:string
b = test
// 没有进行类型声明,类型推断为any
let b
b = 1
b = "2"
unknown&断言
unknown代表未知类型,适用于初期不确定数据类型,需要后期确定,可以理解为一个类型安全的any
let test:unknown
test = 1
test = "2" // 可以赋值任意类型
// unknown类型的变量不能赋值给其他类型
let n:string
/*
n = test 不允许该方式赋值,会类型检测报错, 虽然上面test赋值是一个string
unknown会强制在使⽤之前进⾏类型检查,从⽽提供更强的类型安全性
*/
// 方式一:类型判断
if (typeof a === "string"){
n = test
}
/*
断言是一种告诉编译器我知道这个变量是什么类型的方式
它用于在编译器无法自动推断出正确类型或者推断出的类型不符合开发者期望的情况下,手动指定变量的类型
断言并不会改变变量在运行时的实际类型,只是在编译阶段帮助编译器更好地理解类型
*/
// 方式二:断言 告诉编译器test是string
n = test as string
// 方式三:断言 告诉编译器test是string
n = <string>test
// 读取 any 类型数据的任何属性都不会报错,⽽ unknown 正好与之相反
let str1:any = "hello"
str1.toUpperCase() // 可以正常使用
let str2:unknown = "hello"
str2.toUpperCase() // 不可以正常使用,警告类型未知
// 可以使用断言强制指定str2的类型为string
(str2 as string).toUpperCase() // 可以正常使用
never
never 表示任何值都不是,即:不能有值,例如 undefined 、 null 、 '' 、 0 都不⾏
let test:never // 不能给a赋任何值,任何类型的值都会讲稿
// 限制函数不能有返回值
function test():never{
}
void
void 的含义是空,即:函数不返回任何值,调⽤者也不应依赖其返回值进⾏任何操作,通常用于函数返回值声明
/*
如果函数不编写返回值,有一个隐式的返回值是undefined
虽然函数返回类型为 void ,但是可以接受 undefined
undefined 是 void 可以接受的⼀种空。
*/
// 类型推断默认void
function test(){
}
function test1():void{
return
}
function test2():void{
return undefined
}
function test3():undefined{
}
// 区别在于undefined可以被变量接收
let a = test3()
// void不能被变量接收,会进行警告
let b = test1()
object和Object
object(小写)
所有⾮原始类型,可存储:对象、函数、数组等
let test:object
// 所有非原始类型都符合要求
test = {}
test = [1,2,3]
test = function (){}
// 所有原生类型,赋值都会警告
test = 1 // 进行类型警告
object(大写)
所有可以调⽤ Object ⽅法的类型,除了 undefined 和 null 的任何值
let test:Object
// 可以正常赋值,赋的值都是Object的实例对象
test = {}
test = [1,23]
// 虽然1是原始值,也可以正常赋值,期包装对象是Object的实例,undefined和null以外的原始值都可以
test = 1
// 会进行类型警告,null和undefined原始值没有保证对象
test = null
test = undefined
tuple
元组 (Tuple) 是⼀种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同
元组⽤于精确描述⼀组值的类型, ? 表示可选元素
// 数组必须有两个值,第一个值必须是字符串,第二个必须是数字
let arr:[string,number]
arr = ["1",2]
// 数组第一个值必须是string,第二个值可有可无,如果有,则必须是number
let arr1:[string,number?]
arr1 = ["1"]
arr1 = ["1",2]
// 第一个值必须是number,后面可以是任意数量的string类型,也可以没有
let arr2:[number,...string[]]
arr2 = [1,"2","3"]
arr2 = [1]
arr2 = [1,"2"]
enum
枚举( enum )可以定义⼀组命名常量,它能增强代码的可读性,也让代码更好维护
数字枚举
数字枚举⼀种最常⻅的枚举类型,其成员的值会⾃动递增,且数字枚举还具备反向映射的特点
可以通过值来获取对应的枚举成员名称
enum Test{
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
/*
{
'0': 'Up',
'1': 'Down',
'2': 'Left',
'3': 'Right',
Up: 0,
Down: 1,
Left: 2,
Right: 3
}
*/
console.log(Test)
// 反向映射
console.log(Test.Up) // 0
console.log(Test[0]) // up
// 枚举中的属性是只读的,不能进行赋值操作
// 可以指定枚举成员的初始值,其后的成员值会自增
enum Test{
Up = 6, // 指定初始值是6,后面在6的基础上自增
Down,//7
Left,//8
Right //9
}
// 指定函数的参数类型是Test枚举
function test(v:Test){
if (v == Test.Down){
console.log("ok")
}
}
test(Test.Down)
test(Test.Up)
字符串枚举
enum Test{
Up = "up",
Down = "down"
}
let test:Test = Test.Down
console.log(test) // up
常量枚举
常量枚举是⼀种特殊枚举类型,它使⽤ const 关键字定义,在编译时会被 内联,避免⽣成⼀些额外的代码
内联是 TypeScript 在编译时,会将枚举成员引⽤替换为它们的实际值, ⽽不是⽣成额外的枚举对象。这可以减少⽣成的 JavaScript 代码量,并提⾼运⾏时性能
// 使用普通枚举ts代码
enum Test{
Up,
Down
}
// 编译成js的代码,代码量较大
"use strict";
var Test;
(function (Test) {
Test[Test["Up"] = 0] = "Up";
Test[Test["Down"] = 1] = "Down";
})(Test || (Test = {}));
let t = Test.Up;
// 使用常量枚举ts代码
const enum Test{
Up,
Down
}
let t = Test.Down
// 编译成js代码,代码量较小
"use strict";
let t = 1 /* Test.Down */;
type
type 可以为任意类型创建别名,让代码更简洁、可读性更强,同时能更⽅便地进⾏类型复⽤和扩展
- 基本使用
// 给number类型创建num别名
type num = number
let count:num // 声明count变量类型为num 即number
count = 1
- 联合类型
联合类型是⼀种⾼级类型,它表示⼀个值可以是⼏种不同类型之⼀
// 声明一个Age类型,值可以是number或者string
type Age = number | string
// 声明一个Info类型,值必须是成年或者未成年其中一个
type Info = "成年" | "未成年"
// 声明参数类型是Age
function printAge(age:Age){
console.log(age)
}
// 声明参数类型是Info
function printInfo(info:Info){
console.log(info)
}
// 如果是类型以外的值,会警告
printAge(1)
printAge("1")
printInfo("成年")
printInfo("未成年")
-
交叉类型
交叉类型允许将多个类型合并为⼀个类型。合并后的类型将拥 有所有被合并类型的成员。交叉类型通常⽤于对象类型
type Box = { height:number; weight:number; } type Style = { color:string; px:number t?:number // 可选值 } // 定义类型input,是Box和Style组成的交叉类型 type Input = Box & Style // input中必须包含Box和Style所有字段,可选值除外 const input:Input = { height:100, weight:100, color:"red", px:1, }
自定义对类型声明
声明对象类型
如果要对对象进行类型限制,可以自定义对象的类型
// user对象必须有name属性,类型是string,必须有age属性,类型是number
let user:{name:string,age:number}
user = {name:"l",age:1}
//user 1 必须有name属性,类型是string,age是可选属性,可有可无,如果有的话,类型是number
let user1:{name:string,age?:number} // 使用?标记可选属性
user1 = {name:"1"}
索引签名
定义对象可以具有任意数量的属性,这些属性的键和类型是可变的,可以描述类型不确定的属性(具有动态属性的对象)
// user对象必须有name属性,类型是string,必须有age属性,类型是number
let user: {
name: string,
age: number ,
// [ran:string] 表示key的类型是string,ran是任意自定义名,value的类型是any
[ran:string]:any}
user = {name: "l", age: 1}
user = {name: "l", age: 1,city:"bei"}
// 使用?标记的属性是明确的已知属性,而索引签名是不确定的属性
声明函数类型
// test函数有两个参数,分别是number和string,返回值类型需要是number
// 函数类型声明还可以使⽤:接⼝、⾃定义类型等⽅式
let test:(a1:number,a2:string) => number
test = function (a,b){
console.log(b)
return a
}
test(1,"name")
标签:string,number,ts,test,let,Test,类型
From: https://www.cnblogs.com/Mickey-7/p/18531620