四、类型声明

1、 使⽤ : 来对变量或函数形参,进⾏类型声明

string 声明类型时首字母不能大写

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

类型声明之后填写非该类型code会报错

a = 'hello'
a = 100 //警告:不能将类型“number”分配给类型“string”
b = 666
b = '你好'//警告:不能将类型“string”分配给类型“number”
c = true
c = 666 //警告:不能将类型“number”分配给类型“boolean”
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

函数demo定义传参为x,y时则不能多传,和少传,否则报错

// 参数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 个
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

在 : 后也可以写字⾯量类型,不过实际开发中⽤的不多(了解)

let a: '你好' //a的值只能为字符串“你好”
let b: 100 //b的值只能为数字100
a = '欢迎'//警告:不能将类型“"欢迎"”分配给类型“"你好"”
b = 200 //警告:不能将类型“200”分配给类型“100”
  • 1.
  • 2.
  • 3.
  • 4.

这里的b:类型定义为100 则后续使用时候只能为100类型

五,类型推断

TS 会根据我们的代码,进⾏类型推导,例如下⾯代码中的变量 d ,只能存储数字

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

但要注意,类型推断不是万能的,⾯对复杂类型时推断容易出问题,所以尽量还是明确的编写类 型声明!

六、类型总览

JavaScript 中的数据类型

① string ② number ③ boolean ④ null ⑤ undefined ⑥ bigint ⑦ symbol ⑧ object 备注:其中 object 包含: Array 、 Function 、 Date 、 Error 等......

TypeScript 中的数据类型,(学java的同学,看这些就跟玩似的)我为抓娃添砖JAVA

  1. 上述所有 JavaScript 类型
  2. 六个新类型: ① any ② unknown ③ never ④ void ⑤ tuple ⑥ enum
  3. 两个⽤于⾃定义类型的⽅式: ① type ② interface

注意点:大小写声明

JavaScript 中的这些内置构造函数: NumberStringBoolean ,⽤于 创建对应的包装对象, 在⽇常开发时很少使⽤,在 TypeScript 中也是同理,所以 在 TypeScript 中进⾏类型声明时,通常都是⽤⼩写的 numberstringbo olean

如代码所示:

TS类型说明,类型推断,类型总览,常用类型与语法_函数返回值

  1. 原始类型 VS 包装对象

原始类型:如 number 、 string 、 boolean ,在 JavaScript 中是简单数据 类型,它们在内存中占⽤空间少,处理速度快。

包装对象:如 Number 对象、 String 对象、 Boolean 对象,是复杂类型,在 内存中占⽤更多空间,在⽇常开发时很少由开发⼈员⾃⼰创建包装对象。

  1. ⾃动装箱:JavaScript 在必要时会⾃动将原始类型包装成对象,以便调⽤⽅法或访 问属性

底层自动装箱代码解释:

// 原始类型字符串
let str = 'hello';
str.length
// 当访问str.length时,JavaScript引擎做了以下⼯作:
let size = (function() {
// 1. ⾃动装箱:创建⼀个临时的String对象包装原始字符串
let tempStringObject = new String(str);
// 2. 访问String对象的length属性
let lengthValue = tempStringObject.length;
// 3. 销毁临时对象,返回⻓度值
// (JavaScript引擎⾃动处理对象销毁,开发者⽆感知)
return lengthValue;
})();
console.log(size); // 输出: 5
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

七、常⽤类型与语法

1. any

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

/ 明确的表示a的类型是 any —— 【显式的any】
let a: any
// 以下对a的赋值,均⽆警告
a = 100
a = '你好'
a = false
// 没有明确的表示b的类型是any,但TS主动推断出来b是any —— 隐式的any
let b
//以下对b的赋值,均⽆警告
b = 100
b = '你好'
b = false
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

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

/* 注意点:any类型的变量,可以赋值给任意类型的变量 */
let c:any
c = 9
let x: string
x = c // ⽆警告
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

2. unknown

unknown 的含义是:未知类型,适⽤于:起初不确定数据的具体类型,要后期才能确定

2.1 unknown 可以理解为⼀个类型安全的 any 。
// 设置a的类型为unknown
let a: unknown
//以下对a的赋值,均符合规范
a = 100
a = false
a = '你好'
// 设置x的数据类型为string
let x: string
x = a //警告:不能将类型“unknown”分配给类型“string”
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
2.2 unknown 会强制开发者在使⽤之前进⾏类型检查,从⽽提供更强的类型安全性
// 设置a的类型为unknown
let a: unknown
a = 'hello'
//第⼀种⽅式:加类型判断
if(typeof a === 'string'){
x = a
console.log(x)
}
//第⼆种⽅式:加断⾔
x = a as string
//第三种⽅式:加断⾔
x = <string>a
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
2.3 读取 any 类型数据的任何属性都不会报错,⽽ unknown 正好与之相反
let str1: string
str1 = 'hello'
str1.toUpperCase() //⽆警告
let str2: any
str2 = 'hello'
str2.toUpperCase() //⽆警告
let str3: unknown
str3 = 'hello';
str3.toUpperCase() //警告:“str3”的类型为“未知”
// 使⽤断⾔强制指定str3的类型为string
(str3 as string).toUpperCase() //⽆警告
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

3. never 几乎不用 很少

never 的含义是:任何值都不是,即:不能有值,例如 undefined 、 null 、 '' 、 0 都不⾏

3.1 ⼏乎不⽤ never 去直接限制变量,因为没有意义,例如
/* 指定a的类型为never,那就意味着a以后不能存任何的数据了 */
let a: never
// 以下对a的所有赋值都会有警告
a = 1
a = true
a = undefined
a = null
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
3.2 never ⼀般是 TypeScript 主动推断出来的,例如:
// 指定a的类型为string
let a: string
// 给a设置⼀个值
a = 'hello'
if (typeof a === 'string') {
console.log(a.toUpperCase())
} else {
console.log(a) // TypeScript会推断出此处的a是never,因为没有任何⼀个值符合此处的逻辑
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
3.3 never 也可⽤于限制函数的返回值
// 限制throwError函数不需要有任何返回值,任何值都不⾏,像undeifned、null都不⾏
function throwError(str: string): never {
throw new Error('程序异常退出:' + str)
}
  • 1.
  • 2.
  • 3.
  • 4.

4. void 用于限制函数返回值

void 的含义是空,即:函数不返回任何值,调⽤者也不应依赖其返回值进⾏任何操作!

4.1 void 通常⽤于函数返回值声明

如下调用为正确,但是类型为never时会报错

void,举个例子,你问同学午饭吃啥?他回答never,意思是它不需要吃饭能活着,而void的意思是可以不吃

function logmsg(msg:string):void{
console.log(msg)
return undefined //只有写这个才不会报错 其他的 null [] 都会报错
}
logmsg('你好')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

never

function logmsg(msg:string):never{
console.log(msg)
}
logmsg('你好')
  • 1.
  • 2.
  • 3.
  • 4.

TS类型说明,类型推断,类型总览,常用类型与语法_字符串_02

注意:编码者没有编写 return 指定函数返回值,所以 logMessage 函数是没有显式返回值的,但会有⼀个隐式返回值 ,是 undefined ,虽然函数返回类型为 void ,但也是可以接受 undefined 的,简单记: undefined 是 void 可以接受的⼀种“空”。

4.2 以下写法均符合规范
// 不写 ⽆警告 
function logMessage(msg:string):void{
console.log(msg)
}
// 写return  ⽆警告
function logMessage(msg:string):void{
console.log(msg)
return;
}
// 写undefined ⽆警告
function logMessage(msg:string):void{
console.log(msg)
return undefined
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
4.3 那限制函数返回值时,是不是 undefined 和 void 就没区别呢?— 有区别。因为还有这句话 :【返回值类型为 void 的函数,调⽤者不应依赖其返回值进⾏任何操作!】对⽐下⾯两段代码:
function logMessage(msg:string):void{
console.log(msg)
}
let result = logMessage('你好')
if(result){ // 此⾏报错:⽆法测试 "void" 类型的表达式的真实性
console.log('logMessage有返回值')
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
function logMessage(msg:string):undefined{
console.log(msg)
}
let result = logMessage('你好')
if(result){ // 此⾏⽆警告
console.log('logMessage有返回值')
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

总结 : void不等于undefined,但是void包含undefinedundefinedvoid 的一种具体体现