一、类型声明
使用:来对变量或函数形参,进行类型声明:
typescript
let a: string //变量a只能存储字符串
let b: number //变量b只能存储数值
let c: boolean //变量c只能存储布尔值
a = 'hello'
a = 100 //警告:不能将类型"number"分配给类型"string"
b = 666
b = '你好'//警告:不能将类型"string"分配给类型"number"
c = true
c = 666 //警告:不能将类型"number"分配给类型"boolean"
方法:参数,返回值
typescript
// 参数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 个
在:后也可以写字面量类型,不过实际开发中用的不多。
typescript
let a: '你好' //a的值只能为字符串"你好"
let b: 100 //b的值只能为数字100
a = '欢迎'//警告:不能将类型""欢迎""分配给类型""你好""
b = 200 //警告:不能将类型"200"分配给类型"100"
二、类型推断
TS会根据我们的代码,进行类型推导,例如下面代码中的变量d,只能存储数字
typescript
let d = -99 //TypeScript会推断出变量d的类型是数字
d = false //警告:不能将类型"boolean"分配给类型"number"
但要注意,类型推断不是万能的,面对复杂类型时推断容易出问题,所以尽量还是明确的编写类型声明!
三、类型总览
JavaScript 中的数据类型 | |
---|---|
基本类型 | string number boolean null undefined bigint symbol object |
备注:其中object包含:Array、Function、Date、Error等... |
TypeScript 中的数据类型 | |
---|---|
1. | 上述所有 JavaScript 类型 |
2. 六个新类型: | ①any ②unknown ③never ④void ⑤ tuple ⑥ enum |
3. 两个用于自定义类型的方式: | ①type ②interface |
注意点!
在JavaScript中的这些内置构造函数:Number、String、Boolean,用于创建对应的包装对象, 在日常开发时很少使用,在TypeScript中也是同理,所以在TypeScript中进行类型声明时,通常都是用小写的number、string、boolean
例如下面代码:
typescript
let str1: string
str1 = 'hello'
str1 = new String('hello') //报错
let str2: String
str2 = 'hello'
str2 = new String('hello')
console.log(typeof str1)
console.log(typeof str2)
四、常用类型与语法
- any
any的含义是:任意类型,一旦将变量类型限制为any,那就意味着放弃了对该变量的类型检查。
typescript
// 明确的表示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
注意点:any类型的变量,可以赋值给任意类型的变量
/* 注意点:any类型的变量,可以赋值给任意类型的变量 */
let c:any
c = 9
let x: string
x = c // 无警告
-
unknown
unknown的含义是:未知类型,适用于:起初不确定数据的具体类型,要后期才能确定
-
unknown可以理解为一个类型安全的any。
// 设置a的类型为unknown
let a: unknown
//以下对a的赋值,均符合规范
a = 100
a = false
a = '你好'
// 设置x的数据类型为string
let x: string
x = a //警告:不能将类型"unknown"分配给类型"string"
- unknown会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性。
// 设置a的类型为unknown
let a: unknown
a = 'hello'
//第一种方式:加类型判断
if(typeof a === 'string'){
x = a
console.log(x)
}
//第二种方式:加断言
x = a as string
//第三种方式:加断言
x = a
- 读取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() //无警告
-
never
never的含义是:任何值都不是,即:不能有值,例如undefined、null、''、0都不行!
-
几乎不用never去直接限制变量,因为没有意义,例如:
/* 指定a的类型为never,那就意味着a以后不能存任何的数据了 */
let a: never
// 以下对a的所有赋值都会有警告
a = 1
a = true
a = undefined
a = null
- 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,因为没有任何一个值符合此处的逻辑
}
- never也可用于限制函数的返回值
// 限制throwError函数不需要有任何返回值,任何值都不行,像undeifned、null都不行
function throwError(str: string): never {
throw new Error('程序异常退出:' + str)
}
-
void
void的含义是空,即:函数不返回任何值,调用者也不应依赖其返回值进行任何操作!
-
void通常用于函数返回值声明
function logMessage(msg:string):void{
console.log(msg)
}
logMessage('你好')
注意:编码者没有编写return指定函数返回值,所以logMessage函数是没有显式返回值的,但会有一个隐式返回值 ,是undefined,虽然函数返回类型为void,但也是可以接受undefined的,简单记:undefined是void可以接受的一种"空"。
- 以下写法均符合规范
// 无警告
function logMessage(msg:string):void{
console.log(msg)
}
// 无警告
function logMessage(msg:string):void{
console.log(msg)
return;
}
// 无警告
function logMessage(msg:string):void{
console.log(msg)
return undefined
}
- 那限制函数返回值时,是不是undefined和void就没区别呢?------ 有区别。因为还有这句话 :【返回值类型为void的函数,调用者不应依赖其返回值进行任何操作!】对比下面两段代码:
function logMessage(msg:string):void{
console.log(msg)
}
let result = logMessage('你好')
if(result){ // 此行报错:无法测试 "void" 类型的表达式的真实性
console.log('logMessage有返回值')
}
function logMessage(msg:string):undefined{
console.log(msg)
}
let result = logMessage('你好')
if(result){ // 此行无警告
console.log('logMessage有返回值')
}
理解 void 与 undefined
· void是一个广泛的概念,用来表达"空",而 undefined 则是这种"空"的具体实现。
· 因此可以说 undefined是void能接受的一种"空"的状态。
· 也可以理解为:void包含undefined,但void所表达的语义超越了undefined,void是一种意图上的约定,而不仅仅是特定值的限制。
总结:
如果一个函数返回类型为void,那么:
-
从语法上讲:函数是可以返回undefined的,至于显式返回,还是隐式返回,这无所谓!
-
从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作!即使我们知道它返回了undefined。
-
object
关于object与Object,直接说结论:实际开发中用的相对较少,因为范围太大了。
object(小写)
object(小写)的含义是:所有非原始类型,可存储:对象、函数、数组等,由于限制的范围比较宽泛,在实际开发中使用的相对较少。
let a:object //a的值可以是任何【非原始类型】,包括:对象、函数、数组等
// 以下代码,是将【非原始类型】赋给a,所以均符合要求
a = {}
a = {name:'张三'}
a = [1,3,5,7,9]
a = function(){}
a = new String('123')
class Person {}
a = new Person()
// 以下代码,是将【原始类型】赋给a,有警告
a = 1 // 警告:不能将类型"number"分配给类型"object"
a = true // 警告:不能将类型"boolean"分配给类型"object"
a = '你好' // 警告:不能将类型"string"分配给类型"object"
a = null // 警告:不能将类型"null"分配给类型"object"
a = undefined // 警告:不能将类型"undefined"分配给类型"object"
Object(大写)
· 官方描述:所有可以调用Object方法的类型。
· 简单记忆:除了undefined和null的任何值。
· 由于限制的范围实在太大了!所以实际开发中使用频率极低。
let b:Object //b的值必须是Object的实例对象(除去undefined和null的任何值)
// 以下代码,均无警告,因为给a赋的值,都是Object的实例对象
b = {}
b = {name:'张三'}
b = [1,3,5,7,9]
b = function(){}
b = new String('123')
class Person {}
b = new Person()
b = 1 // 1不是Object的实例对象,但其包装对象是Object的实例
b = true // truue不是Object的实例对象,但其包装对象是Object的实例
b = '你好' // "你好"不是Object的实例对象,但其包装对象是Object的实例
// 以下代码均有警告
b = null // 警告:不能将类型"null"分配给类型"Object"
b = undefined // 警告:不能将类型"undefined"分配给类型"Object"
声明对象类型
- 实际开发中,限制一般对象,通常使用以下形式
// 限制person1对象必须有name属性,age为可选属性
let person1: { name: string, age?: number }
// 含义同上,也能用分号做分隔
let person2: { name: string; age?: number }
// 含义同上,也能用换行做分隔
let person3: {
name: string
age?: number
}
// 如下赋值均可以
person1 = {name:'李四',age:18}
person2 = {name:'张三'}
person3 = {name:'王五'}
// 如下赋值不合法,因为person3的类型限制中,没有对gender属性的说明
person3 = {name:'王五',gender:'男'} 作者:尚硅谷 https://www.bilibili.com/read/cv37465036/?spm_id_from=333.999.0.0\&jump_opus=1 出处:bilibili