7

TypeScript查漏补缺(基础类型)

 2 years ago
source link: https://www.clzczh.top/2022/06/18/typescript-9/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

TypeScript查漏补缺(基础类型)

TypeScript 入门教程看完了,大部分都按自己的理解来做了下笔记输出。但是,总感觉有遗漏的知识点。于是,找了一些大佬的博客,来查漏补缺一下。(但是这里只记录一下基本类型的,因为其他部分暂时看的还有点云里雾里)

主要补充之前的笔记中没有的讲到的类型。

unknown类型

unknown类型是any类型对应的安全类型。

**所有类型都可以赋值给any,也可以赋值给unknown**。

// unknown
let myunknown: unknown

myunknown = 123
myunknown = 'hello'

// any
let myany: any

myany = 123
myany = 'hello'

// number
let mynumber: number

mynumber = 123
mynumber = 'hello' // 报错:不能将类型“string”分配给类型“number”。

any类型能被赋值给任意类型(anyunknownnumber等,unknown类型只能被赋值给unknownany类型)

// unknown
let myunknown: unknown

let value1: unknown = myunknown
let value2: any = myunknown
let value3: number = myunknown // 报错:不能将类型“unknown”分配给类型“number”。


// any
let myany: any

let value4: unknown = myany
let value5: any = myany
let value6: number = myany

any类型的值进行操作无需检查,unknown类型需要检查

// unknown
let myunknown: unknown
console.log(myunknown.name) // 报错:类型“unknown”上不存在属性“name”。

// any
let myany: any
console.log(myany.name)

上面的例子简单讲一下本人的理解:任意类型any顾名思义,值可以是任意类型,也就包括是对象,而对象可能会有name,所以就不会报错。但是,unknown类型就会不知道该类型究竟存储了什么类型的值,虽然它也可能是对象,但是为了安全着想,会报错。**unknown类型是any类型对应的安全类型。**

void类型

void类型表示没有任何类型。一般用来声明没有返回值的函数。(实际上,返回undefinednull也是可行的,void类型更像是不会返回有用的值)

function sayHello(): void {
console.log('Hello')
}

sayHello()

但是,这里又有一个疑问:函数没有返回值时,默认返回undefined

那么,声明函数时的void类型和undefined类型有什么区别呢?

返回值为undefined类型必须有返回值

虽然**函数没有返回值时,默认返回undefined**,但是当我们指定函数的返回值为undefined类型时,没有返回值会报错。

function sayHello(): void {
console.log('Hello')
}

console.log(sayHello())


function sayHi(): undefined {
console.log('Hi')
}
0797eb0a70284717a9c5b18e6382eb8a~tplv-k3u1fbpfcp-zoom-1.image

undefined能被赋值给void,但void不能赋值给undefined

void类型不能赋值给undefined这是符合正常的情况的:即只能赋值给自己和any类型

function sayHello(): void {
console.log('Hello')
}

const s1: undefined = sayHello() // 报错
const s2: void = sayHello()
const s3: null = sayHello() // 报错
202206181250687.png

但是,有例外情况:undefined可以被赋值给void

const s1: undefined = undefined
const s2: void = undefined

顺带提一下:nullundefined的关系还是依然难解难分

const s1: null = undefined
const s2: undefined = null

never类型

never类型表示永不存在的值的类型。如抛出异常或不会有返回值的函数的返回值类型。

也就是说:如果看到never类型,很有可能是代码出问题了。

function errFunc(): never {
throw new Error('clz')
}

function infiniteLoop(): never {
while (true) { }
}

可以看下官方提示(VSCode翻译版)

2fb5d9ee945c47539792a6a404600b93~tplv-k3u1fbpfcp-zoom-1.image

那么,never类型有什么用途呢?毕竟按上面的写法的话,就像是只能手动制造bug一样。
在TS中,可以利用never类型来实现详细的检查

type Nickname = string | number

function checkNickname(nickname: Nickname) {
if (typeof nickname === 'string') {
console.log(`你的昵称是string类型${nickname}`)
} else if (typeof nickname === 'number') {
console.log(`你的昵称是number类型${nickname}`)
} else {
throw new Error('请检查类型')
}
}

checkNickname('赤蓝紫')

checkNickname(123)

checkNickname(true)
c36989148cb444879fb566ee3fa465a9~tplv-k3u1fbpfcp-zoom-1.image

从上面的例子中,可以看到checkNickname只是接受stringnumber类型,当我们传boolean类型的时候,会在编译期间报错。

但是,当同事修改Nickname的类型为string | number | boolean时,而且没修改checkNickname的逻辑的话,就会出问题。

202206181250709.png

可以发现:我们传参为boolean时,会在运行时抛出我们自定义的错误,但是再编译时没法检测出问题。这时候就能利用never来实现编译时就检测出问题。

c862f2c547394b80a592d252acc40f0b~tplv-k3u1fbpfcp-zoom-1.image

上面的例子中,else分支的nickname会被收窄为boolean类型,而boolean类型无法被赋值给never类型,所以会出现编译错误,就能够提前检测出错误,避免很多没必要的问题。

使用never类型能够避免新增联合类型,但是没有对应实现的情况

参考链接:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK