TS: 类型断言

2024-06-15 16:44
文章标签 类型 ts 断言

本文主要是介绍TS: 类型断言,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

案例:


function useFetch() {
    const name: string = "跳跳";
    const age: number = 18;
    return [name, age] as const;
    }
//这里如果不使用 as const 会发现 我们结构出来的数组类型是name: string | number
// 使用完 as const 以后 为string,as const 也叫类型断言

问:


function useFetch() {
    const name: string = "跳跳";
    const age: number = 18;
    return [name, age] as const;
    }
//这里如果不使用 as const 会发现 我们结构出来的数组类型是name: string | number
// 使用完 as const 以后 为string,as const 也叫类型断言
useFetch()这里的 as const是什么?

回答:

在上述代码中,as const 是 TypeScript 中的类型断言语法,用于告诉编译器将一个值作为字面量类型进行推断。在这个特定的例子中,as const 被用于返回了一个元组类型的数组。

当不使用 as const 时,name 和 age 的类型会被推断为 string | number,这是因为 TypeScript 会根据赋值语句的右侧值的类型进行推断,并将其应用于变量的类型。在这种情况下,等号右边的值是一个由 string 和 number 类型构成的数组,因此 TypeScript 推断出 name 和 age 可以是 string 或 number 类型的联合类型。

然而,通过使用 as const,我们告诉 TypeScript 将返回的数组视为不可变的常量(const),并且要将其中的每个元素的类型也视为字面量类型。这样,name 和 age 就被正确地推断为 string 和 number 类型,而不是联合类型。

总结来说,as const 的作用是将一个表达式的类型断言为其整体字面量类型,从而避免出现联合类型。这在需要确保类型的精确性和确定性时非常有用

问:

不是太懂 什么是联合类型 为什么一定要用as const 这里的const指的什么?

回答:

联合类型是 TypeScript 中一种表示一个值可以是多种类型之一的方式。比如,如果一个变量可能是 string 或 number 类型,你可以使用联合类型来表示这一点:

```typescript
let myVar: string | number;
```

这样声明的变量 myVar 就可以存储 string 类型或者 number 类型的值。

在你的代码中,如果不使用 as const,TypeScript 会根据返回的数组推断出 name 和 age 的类型是 string | number,因为 TypeScript 会将元组中的每个元素都视为联合类型的候选项。

而当你使用 as const 时,你告诉 TypeScript 将返回的数组视为不可变的常量(const),并且要将其中的每个元素的类型也视为字面量类型。这样,name 和 age 就会被正确地推断为字面量类型,而不是联合类型。

所以,as const 这里的 const 指的是将数组中的元素作为字面量类型来对待,而不是联合类型。这样可以确保返回的数组中的元素类型是确定的,而不是多种可能性的联合类型

问:

所以类型断言的写法就是as const吗?

回答:

`as const` 是 TypeScript 中的一种特殊的类型断言,用于将一个值的类型推断为其字面量类型和只读属性。它可以用于确保对象、数组等结构在类型系统中被视为不可变和精确的类型。在你的示例中,`as const` 确保了返回的元组类型是 `[string, number]`,而不是更宽泛的 `(string | number)[]`。

不过,`as const` 并不是唯一的类型断言方式。TypeScript 还有其他类型断言语法,可以更灵活地处理类型转换。这些断言通常用于告诉编译器你比它更了解特定值的类型。

### 常见的类型断言语法

1. **尖括号语法** (不推荐在 JSX 中使用,因为会与 JSX 语法冲突):

```type
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
```

2. **`as` 语法**(推荐使用):

```typescript
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
```

### `as const` 的具体用途

`as const` 用于将一个对象、数组或其他结构转变为字面量类型,并使其不可变。来看一个具体的例子:

```typescript
const myArray = [10, 20] as const;
```

在这个例子中,`myArray` 的类型将被推断为 `[10, 20]`,而不是 `(number | number)[]` 或 `number[]`。这意味着 `myArray` 是一个包含两个具体数值(10 和 20)的元组,并且这些数值是只读的,不可更改。

### 更详细的例子

```typescript
function useFetch() {
    const name: string = "跳跳";
    const age: number = 18;
    return [name, age] as const;
}

// 调用 useFetch 并解构结果
const [name, age] = useFetch();

// 在这个例子中,name 和 age 的类型分别是 "跳跳" 和 18,而不是 string 和 number。
```

在这个例子中,`as const` 确保 `useFetch` 返回的数组被视为一个具体的字面量类型 `[string, number]` 的元组,而不是一个任意的 `(string | number)[]` 数组。

### 总结

- **`as const`**: 用于将一个表达式的类型断言为其字面量类型,使其不可变。
- **类型断言 (`as` 或 `<...>`)**: 用于告诉 TypeScript 一个值的确切类型,从而覆盖默认的类型推断。

希望这些解释能帮助你更好地理解 `as const` 和其他类型断言的用法。如果还有其他问题,欢迎继续提问!

问:

所以上面的useFetch函数中的 name和age是只读的是吗?

回答:

是的,当你在 `useFetch` 函数中使用 `as const` 时,返回的元组中的元素(即 `name` 和 `age`)会被视为字面量类型,并且是只读的。

为了更清楚地说明这一点,我们可以看一下 TypeScript 是如何处理 `as const` 的:

```typescript
function useFetch() {
    const name: string = "跳跳";
    const age: number = 18;
    return [name, age] as const;
}

// 调用 useFetch 并解构结果
const [name, age] = useFetch();
```

在这个例子中,`useFetch` 返回的是一个 `[string, number]` 类型的元组,并且每个元素都是只读的。换句话说,`name` 和 `age` 的值不能被改变:

```typescript
const result = useFetch();
// result 的类型是 readonly ["跳跳", 18]

const [name, age] = result;
// name 的类型是 "跳跳"
// age 的类型是 18

// 试图修改 name 或 age 的值将导致编译错误
// name = "新的名字"; // 错误: Cannot assign to 'name' because it is a read-only property.
// age = 20;         // 错误: Cannot assign to 'age' because it is a read-only property.
```

所以,使用 `as const` 不仅确定了返回数组中的元素类型是字面量类型,还确保了这些元素是不可变的,即只读的。

### 深入理解 `readonly`

返回的数组实际上是一个包含只读属性的元组,实际上是`Readonly<[string, number]>`。这意味着不仅数组本身是只读的,数组内的元素也是只读的。

### 总结

- 使用 `as const` 会将数组或对象的类型断言为不可变的字面量类型。
- 在函数 `useFetch` 中,返回的元组 `[name, age]` 被视为只读的字面量类型,因此你不能修改它们的值。

这种做法在一些需要确保数据不被意外修改的场景中非常有用,比如 Redux 状态管理中的不可变状态。希望这个解释能帮助你更好地理解 `as const` 的作用和用途!

这篇关于TS: 类型断言的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064007

相关文章

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

IDEA如何将String类型转json格式

《IDEA如何将String类型转json格式》在Java中,字符串字面量中的转义字符会被自动转换,但通过网络获取的字符串可能不会自动转换,为了解决IDEA无法识别JSON字符串的问题,可以在本地对字... 目录问题描述问题原因解决方案总结问题描述最近做项目需要使用Ai生成json,可生成String类型

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

Python中异常类型ValueError使用方法与场景

《Python中异常类型ValueError使用方法与场景》:本文主要介绍Python中的ValueError异常类型,它在处理不合适的值时抛出,并提供如何有效使用ValueError的建议,文中... 目录前言什么是 ValueError?什么时候会用到 ValueError?场景 1: 转换数据类型场景

C# dynamic类型使用详解

《C#dynamic类型使用详解》C#中的dynamic类型允许在运行时确定对象的类型和成员,跳过编译时类型检查,适用于处理未知类型的对象或与动态语言互操作,dynamic支持动态成员解析、添加和删... 目录简介dynamic 的定义dynamic 的使用动态类型赋值访问成员动态方法调用dynamic 的

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s