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 支持三种访问修饰符:

  1. public:成员可以被任何代码访问。这是默认的访问修饰符。
  2. private:成员只能在定义它的类内部访问。
  3. protected:成员只能在定义它的类及其子类中访问。

与C#相同,ts中也可以使用readonly来标识只读属性

接口

在ts中,接口的作用不只是定义类,同样还可以用来定义对象结构和函数结构

在ts中,接口可以重复定义,所有接口中的结构定义最后会被合并(需要同时满足)

接口的使用场景:

  • 定义对象格式:描述类型数据、API响应格式、配置对象等等
  • 类的契约:规定一个类需要实现的哪些属性和方法
  • 自动合并:一般用于扩展第三方库的类型,在大型项目中很可能会用到

一些相似概念的区别

interface和type都可以定义对象结构,两者在很多场景都可以互换

不同点:

  • interface:更专注于用于类和对象的定义,并且支持自动合并和继承
  • type:可以定义类型的别名、联合类型、交叉类型,但不支持继承和合并

类型定义文件

类型声明文件是Ts中的一种特殊文件,通常以.d.ts作为文件扩展名,他的主要作用是为现有的JavaScript代码提供类型信息,使得TypeScript能够在这些使用JavaSript库或模块时进行类型检查或提示