TypeScript 知识点

89 阅读9分钟

一: 类型声明

let a: string //变量a只能存储字符串
let b: number //变量a只能存储数值
let c: boolean //变量a只能存储布尔值

a = 'hello'
a = 100 //警告:不能将类型“number”分配给类型“string”

b = 666
b = '你好'//警告:不能将类型“string”分配给类型“number”

c = true
c = 666 //警告:不能将类型“number”分配给类型“boolean”

// 参数x必须是数字,参数y也必须是数字,函数返回值也必须是数
function demo(x:number,y:number):number{
    return x + y
}

demo(100,200)
demo(100,'200') //警告:类型“string”的参数不能赋给类型“number”的参数
demo(100,200,300) //警告:应有 2 个参数,但获得 3 个
demo(100) //警告:应有 2 个参数,但获得 1 个

二. 类型推断

let d = -99 //TypeScript会推断出变量d的类型是数字 隐式
d = false //警告:不能将类型“boolean”分配给类型“number”

三类型总览

JavaScript 中的数据类型:

stringnumberbooleannullundefinedbigintsymbolobject

备注:其中 object 包含: Array 、 Function 、 Date ......

TypeScript 中的数据类型:

 以上所有
 四个新类型: voidneverunknownanyenum 、 tuple
 ⾃定义类型: typeinterface

注意点: JS 中的这三个构造函数: Number 、 String 、 Boolean ,他们只⽤于包装对象,正常开发时,很少去使⽤他们,在 TS 中也是同理。

let n = 56
n.toFixed(2)
/*
当执⾏n.toFixed(2) ,底层做了这⼏件事:
1.let temp = new Number(42)
2.value = temp.toFixed(2)
3.删除value
4.返回value
*/

类型总览:

类型描述举例
numer任意数字1,-33,3.8
string任意字符串‘hello’,'ok','你好'
boolean布尔值 true 或者falsetrue false
字面量值只能是字面量值值本身
any任意类型1,‘hello’,true
nunkown类型安全的any1,‘hello’,true
never不能是任何值无值
void空或undefined空或undefined
object任意js对象object,array,function
tuple元素,TS新增类型,固定长度数组[1,2]
enum枚举,TS新增类型enum{a,b}

四:常⽤类型

字面量

let a: '你好' //a的值只能为字符串“你好”
let b: 100 //b的值只能为数字100
a = '欢迎'//警告:不能将类型“"欢迎"”分配给类型“"你好"”
b = 200 //警告:不能将类型“200”分配给类型“100”
let gender: '男'|'⼥' //定义⼀个gender变量,值只能为字符串“男”或“⼥”
gender = '男'
gender = '未知' //不能将类型“"未知"”分配给类型“"男" | "⼥"

any

any 的含义是:任意类型,⼀旦将变量类型限制为 any ,那就意味着放弃了对该变量的类型检查。

//明确的表示a的类型是any —— 显式的any
let a: any
//以下对a的赋值,均⽆警告
a = 100
a = '你好'
a = false

//没有明确的表示b的类型是any,但TS主动推断了出来 —— 隐式的any
let b
//以下对b的赋值,均⽆警告
b = 100
b = '你好'
b = false

注意点: any 类型的变量,可以赋值给任意类型的变

/* 注意点:any类型的变量,可以赋值给任意类型的变量 */
let a
let x: string
x = a // ⽆警告

unknown

unknown 的含义是:未知类型。

备注1: unknown 可以理解为⼀个类型安全的 any

备注2: unknown 适⽤于:开始不知道数据的具体类型,后期才能确定数据的类型

// 设置a的类型为unknown
let a: unknown

//以下对a的赋值,均正常
a = 100
a = false
a = '你好'

// 设置x的数据类型为string
let x: string
x = a //警告:不能将类型“unknown”分配给类型“string”

若就是想把 a 赋值给 x ,可以⽤以下三种写法:

// 设置a的类型为unknown

let a: unknown
a = 'hello'

//第⼀种⽅式:加类型判断
if(typeof a === 'string'){
    x = a
}

//第⼆种⽅式:加断⾔
x = a as string
//第三种⽅式:加断⾔
x = <string>a

any 后点任何的东⻄都不会报错,⽽ unknown 正好与之相反。

let str1: string = 'hello'
str1.toUpperCase() //⽆警告

let str2: any = 'hello'
str2.toUpperCase() //⽆警告

let str3: unknown = 'hello';
str3.toUpperCase() //警告:“str3”的类型为“未知”

// 使⽤断⾔强制指定str3的类型为string
(str3 as string).toUpperCase() //⽆警告

never

never 的含义是:任何值都不是,简⾔之就是不能有值, undefined 、 null 、 '' 、 0 都不⾏!

1. ⼏乎不⽤ never 去直接限制变量,因为没有意义,例如:

/* 指定a的类型为never,那就意味着a以后不能存任何的数据了 */
let a: never

// 以下对a的所有赋值都会有警告
a = 1
a = true
a = undefined

2. never ⼀般是 TypeScript 主动推断出来的,例如:

// 指定a的类型为string
let a: string

// 给a设置⼀个值
a = 'hello'
if(typeof a === 'string'){
    a.toUpperCase()
}else{
console.log(a) // TypeScript会推断出此处的a是never,因为没有任何⼀个值符合此处的逻辑

}

3. never 也可⽤于限制函数的返回值

// 限制demo函数不需要有任何返回值,任何值都不⾏,像undeifned、null都不⾏
function demo():never{
    throw new Error('程序异常退出')
}

void

void 的含义是: 空 或 undefined ,严格模式下不能将 null 赋值给 void 类型。

let a:void = undefined
//严格模式下,该⾏会有警告:不能将类型“null”分配给类型“void”
let b:void = null

void 常⽤于限制函数返回值

// ⽆警告
function demo1():void{
}

// ⽆警告
function demo2():void{
    return
}

// ⽆警告
function demo3():void{
    return undefined
}

// 有警告:不能将类型“number”分配给类型“void”
function demo4():void{
    return 666
}

object

关于 Object 与 object ,直接说结论:在类型限制时, Object ⼏乎不⽤,因为范围太⼤了,⽆意义。

1. object 的含义:任何【⾮原始值类型】,包括:对象、函数、数组等,限制的范围⽐较宽泛,⽤的少。

let a:object //a的值可以是任何【⾮原始值类型】,包括:对象、函数、数组等

// 以下代码,是将【⾮原始类型】赋给a,所以均⽆警告
a = {}
a = {name:'张三'}
a = [1,3,5,7,9]
a = function(){}

// 以下代码,是将【原始类型】赋给a,有警告
a = null // 警告:不能将类型“null”分配给类型“object”
a = undefined // 警告:不能将类型“undefined”分配给类型“object”
a = 1 // 警告:不能将类型“number”分配给类型“object”
a = true // 警告:不能将类型“boolean”分配给类型“object”
a = '你好' // 警告:不能将类型“string”分配给类型“object

2. Object 的含义: Object 的实例对象,限制的范围太⼤了,⼏乎不⽤。

let a:Object //a的值必须是Object的实例对象,
// 以下代码,均⽆警告,因为给a赋的值,都是Object的实例对象
a = {}
a = {name:'张三'}
a = [1,3,5,7,9]
a = function(){}
a = 1 // 1不是Object的实例对象,但其包装对象是Object的实例
a = true // truue不是Object的实例对象,但其包装对象是Object的实例
a = '你好' // “你好”不是Object的实例对象,但其包装对象是Object的实例

// 以下代码均有警告
a = null // 警告:不能将类型“null”分配给类型“Objecta = undefined // 警告:不能将类型“undefined”分配给类型“Object

3. 实际开发中,限制⼀般对象,通常使⽤以下形式

// 限制person对象的具体内容,使⽤【,】分隔,问号?代表可选属性 如age可以没有可以有
let person: { name: string, age?: number}

// 限制car对象的具体内容,使⽤【;】分隔,必须有price和color属性,其他属性不去限制,有没有都⾏ 

let car: { price: number; color: string; [k:string]:any} 
K: 任意字符串也可以XX   
let car2={price:121,color:"black"}

// 限制student对象的具体内容,使⽤【回⻋】分隔
let student: {
    id: string
    grade:number
}

// 以下代码均⽆警告
person = {name:'张三',age:18}
person = {name:'李四'}
car = {price:100,color:'红⾊'}
student = {id:'tetqw76te01',grade:3}

4. 限制函数的参数、返回值,使⽤以下形式

let demo: (a: number, b: number) => number
demo = function(x,y) {
    return x+y
}

5. 限制数组,使⽤以下形式

let arr1: string[] // 该⾏代码等价于: let arr1: Array<string>
let arr2: number[] // 该⾏代码等价于: let arr2: Array<number>

arr1 = ['a','b','c']
arr2 = [1,3,5,7,9]

tuple

tuple 就是⼀个⻓度固定的数组。

let t: [string,number]
t = ['hello',123]

// 警告,不能将类型“[string, number, boolean]”分配给类型“[string, number]t = ['hello',123,false]

enum

enum 是枚举

// 定义⼀个枚举

enum Color {
Red,
Blue,
Black,
Gold
}

// 定义⼀个枚举,并指定其初识数值

enum Color2 {
Red = 6,
Blue,
Black,
Gold

}

console.log(Color)
/*
    {
    0: 'Red',
    1: 'Blue',
    2: 'Black',
    3: 'Gold',
    Red: 0,
    Blue: 1,
    Black: 2,
    Gold: 3
    }
*/

console.log(Color2)
/*
    {
    6: 'Red',
    7: 'Blue',
    8: 'Black',
    9: 'Gold',
    Red: 6,
    Blue: 7,
    Black: 8,
    Gold: 9
    }
*/

// 定义⼀个phone变量,并设置对⻬进⾏限制
let phone: {name:string,price:number,color:Color}
phone = {name:'华为Mate60',price:6500,color:Color.Red}
phone = {name:'iPhone15Pro',price:7999,color:Color.Blue}

if(phone.color === Color.Red){
    console.log('⼿机是红⾊的')
}

举例2:

image.png

⾃定义类型

⾃定义类型,可以更灵活的限制类

image.png

抽象类

常规类:

image.png

继承

image.png

抽象类:不能去实例化,但可以被别⼈继承,抽象类⾥有抽象⽅法

image.png

接⼝

1. 接⼝⽤于限制⼀个类中包含哪些属性和⽅法:

image.png

2. 接⼝是可以重复声明的:

image.png

3. 【接⼝】与【⾃定义类型】的区别:

接⼝可以:

  1. 当⾃定义类型去使⽤;
  2. 可以限制类的结构;

⾃定义类型:

  1. 仅仅就是⾃定义类型;

image.png

4. 【接⼝】与【抽象类】的区别

抽象类:

  1. 可以有普通⽅法,也可以有抽象⽅法;
  2. 使⽤ extends 关键字去继承抽象类;

接⼝中:

  1. 只能有抽象⽅法;
  2. 使⽤ implements 关键字去实现接⼝

抽象类举例:

image.png

接⼝举例:

image.png

属性修饰符

image.png

泛型

  • 定义⼀个函数或类时,有些情况下⽆法确定其中要使⽤的具体类型(返回值、参数、属性的类型不能确定),此时就需要泛型了

举例: <T> 就是泛型,(不⼀定⾮叫 T ),设置泛型后即可在函数中使⽤ T 来表示该类型

image.png

image.png

总结

类型声明

对象

1、用? 代表属性可有可无  如:age可以写可以不写
let a:{name:string,age?:number}
2、用[xx:String]:any  ,后面的属性可有可无
let b:{name:string,[proName:string]:any}
 b={name:'hi',age:'100',sex:'name'} 正确,如不写name就报错

数组

1:字符串的数组
 let a:string[]  也可以  let Array<string>  
 
 2: 元祖:固定长度的数组
 let b:[string,string]
 b=['1',‘2’]  //  正确
 b=['1','2','3'] //错误
 

符号

| 或  & 同时

let a:string|number
a="1" 或者 a=1

类型别名

type myType= 1|2|3|4|8
let k:myType
let G:myType