TS
TS
TypeScript(简称 TS)是由微软开发的一种开源的编程语言,它是 JavaScript 的一个超集,意味着所有的 JavaScript 代码都是有效的 TypeScript 代码。TypeScript 的主要特点是添加了静态类型检查,这使得开发者可以在编译时发现并修复许多类型的错误,从而提高代码的质量和可维护性。
数据类型
JS的数据类型
- string
- number
- boolean
- null
- undefined
- bigint
- symbol
- object:其中包含Array、Function、Date等
TS增加了六种新的数据类型
- any
- unknow
- never
- void
- tuple
- enum
两个用于自定义类型的方式
- type
- interface
常用的数据类型
any
// 显示定义any
let a: any
// 隐式的定义any
let b
注意:any类型的对象,可以赋值给任意有数据类型的变量,这是一个非常破坏性的事情
使用any类型的对象,意味着后续对这个对象舍弃了所有静态类型检查
unknow
unknow可以理解为一个数据安全的any,但无法将unknown的对象赋值给有数据类型的对象(相对any更为安全)
let a: unknow
a = 'hello'
let x: string
// 第一种方式,类型判断后赋值
if(typeof a === "string"){
x = a
}
// 第二种方式,断言(ts语法)
x = a as string
// 第三种方式,断言
x = <string>a
never
通过never来修饰函数没有任何返回值,这里需要注意,在ts中,一个函数的默认返回值是undefined,这和void返回空值是不一样的
function demo():never{
throw new Error("程序运行异常!!")
}
void
- void通常用于函数返回值的声明,返回值为空的函数以void标识
- void可以接受函数的默认返回值undefined
- 不应该依赖以void标识的函数的返回值进行任何操作
object
开发中一般不使用object来做类型限制,因为object的范围过于宽泛,可以为任意引用类型
在这里Object的范围更加宽泛,除了null和undefined这两个类型,其他能够调用Object方法(.toString)都可以储存
声明对象类型
let person:{
// 这里的分隔符可以是逗号,分号,甚至是回车换行
name: string,
age?: int // 使用问好来标注此属性可以为空
}
person = {name:"xiaobai" , age: 18}
person = {name:"xiaobai"}
添加索引签名,string类型的key,其值可以为任意值
添加索引签名后,此对象可以有任意数量的属性
let person:{
// 这里的分隔符可以是逗号,分号,甚至是回车换行
name: string,
age?: int // 使用问好来标注此属性可以为空
[key:string]:any
}
person = {name:"xiaobai" , age: 18}
person = {name:"xiaobai"}
声明函数类型
- JavaScript:由于是动态类型语言,实现回调十分简单,没有类型的限制。
- C#:为了实现类型安全的回调机制,开发了委托功能,因为它是强类型语言。
- TypeScript:虽然是基于 JavaScript 的,但由于引入了静态类型检查,也需要使用类似委托的方式来定义回调,以确保类型安全。
let count: (a:number,b:number) => number
count = function(a,b){
return a+b
}
声明数组类型
let arr: string[]
arr = ['a','b','c']
let arr1: Array<string>
tuple
tuple元组是一种特殊的数组类型,可以存储固定数量的元素,并且元素类型也是固定类型的
let arr1: [string,number]
arr1 = ["xiaobai" , 18]
let arr2: [string,number?]
arr2 = ["xiaobai" , 18]
let arr3: [string,...number[]]
arr3 = ["xiaobai", 1 , 2 , 3]
枚举
枚举(enum)是一组命名常量,他能增强代码的可读性,让代码更好维护
enum Direction{
Up,
Down,
Left,
Right
}
console.log(Direction[0]) // 取到Up
使用关键字const定义枚举,在编译到js代码后,会在编译时进行内联,避免生成多余的代码
const enum Direction{
Up,
Down,
Left,
Right
}
console.log(Direction[0]) // 取到Up
type
type是一个自定义类型关键字
使用type可以定义联合类型
// 定义新的类型,可以为number或者string
type Status = number | string
// 定义新的字面量类型
type Gender = '男' | '女'
使用type可以定义交叉类型
在这里,House类型的对象必须有Area和Address的属性,且属性类型必须对应
type Area = {
height: number; // 高
width: number; // 宽
}
type Address = {
num: number // 楼号
cell: number // 单元号
room: string // 房间号
}
type House = Area & Address
使用type定义函数类型
这里有一个特殊情况:
- 当定义函数时就定义了返回值类型,则会严格要求返回值类型
- 当定义函数时没有严格定义返回值类型,而是通过一个type定义一个返回值为void的函数类型,在以此来约束函数,则返回值类型不那么严格要求
type LogFunc = () => void
const f1:LogFunc = function(){
return "xiaobai" // 不严格要求返回值类型为void
}
类和接口
在ts中,类的代码可以进行简写
// 简写前代码
class Person{
name: string
age: number
constructor(name:string, age:number){
this.name = name
this.age = age
}
}
// 简写后代码
class Person{
constructor(
public name: string,
public age: number
){}
}
访问修饰符
TypeScript 支持三种访问修饰符:
public
:成员可以被任何代码访问。这是默认的访问修饰符。private
:成员只能在定义它的类内部访问。protected
:成员只能在定义它的类及其子类中访问。
与C#相同,ts中也可以使用readonly来标识只读属性
接口
在ts中,接口的作用不只是定义类,同样还可以用来定义对象结构和函数结构
在ts中,接口可以重复定义,所有接口中的结构定义最后会被合并(需要同时满足)
接口的使用场景:
- 定义对象格式:描述类型数据、API响应格式、配置对象等等
- 类的契约:规定一个类需要实现的哪些属性和方法
- 自动合并:一般用于扩展第三方库的类型,在大型项目中很可能会用到
一些相似概念的区别
interface和type都可以定义对象结构,两者在很多场景都可以互换
不同点:
- interface:更专注于用于类和对象的定义,并且支持自动合并和继承
- type:可以定义类型的别名、联合类型、交叉类型,但不支持继承和合并
类型定义文件
类型声明文件是Ts中的一种特殊文件,通常以.d.ts作为文件扩展名,他的主要作用是为现有的JavaScript代码提供类型信息,使得TypeScript能够在这些使用JavaSript库或模块时进行类型检查或提示