TypeScript 学习笔记(八):类型断言

前言

在上一篇文章TypeScript 学习笔记(七):泛型中我们学习了TS中的函数类型,本篇文章我们主要了解TS中的类型断言

如果你也和我一样在为大厂冲刺的话,欢迎添加我的微信lx3122178991,这里有一群小伙伴有着和你同样的目标,欢迎来一起讨论,一同进步。

类型断言是什么

TS对于没有进行类型声明的值进行类型推断,但是很多时候得到的结果并不是想要的结果。就比如下面这个例子。

TS 复制代码
type T = 'a'|'b'|'c';
let foo = 'a';

let bar:T = foo; // 报错

在这个例子中,TS推断变量foo的类型是string,但是变量bar的类型是'a'|'b'|'c',前者是后者的父类型,父类型不能赋值给子类型。所以就最后一行报错了。

为了解决这一个问题,TS提供了类型断言 这样一种手段,允许在代码中"断言"某个值的类型,告诉编译器此处的值是什么类型。TS一旦发现存在类型断言,就不再对该值进行类型推断,而是直接采用断言给出的类型。

所以上面的例子可以改成这样。

TS 复制代码
type T = 'a'|'b'|'c';

let foo = 'a';
let bar:T = foo as T; // 正确

最后一行的foo as T表示告诉编译器,变量foo的类型断言为T,所以这一行不再需要类型推断了,编译器直接把foo的类型当作T,就不会报错了。

类型断言的语法

类型断言有两种语法。

TS 复制代码
// 语法一:<类型>值
<Type>value

// 语法二:值 as 类型
value as Type

上面两种语法是等价的,value表示值,Type表示类型。早期只有语法一,后来因为TS开始支持ReactJSX语法,为了避免两者冲突,就引入了语法二。

类型断言的使用条件

类型断言并是把某个值断言为任意类型。 下面的例子中,变量n是数值,无法把它断言成字符串,TS就会报错。

TS 复制代码
const n = 1;
const m:string = n as string; // 报错

类型断言的使用前提是,值的实际类型与断言的类型必须满足一个条件。 valueType的子类型,或者Typevalue的子类型。

TS 复制代码
value as Type

但是,如果真的要断言成一个完全无关的类型,也是可以做到的。

那就是连续进行两次类型断言,先断言成unknown类型或any类型,然后再断言为目标类型。因为any类型和unknown类型是所有其他类型的父类型,所以可以作为两种完全无关的类型的中介。

TS 复制代码
value as unknown as Type

as const 断言

TS中,如果没有声明变量类型,let 命令声明的变量,会被类型推断为TS内置的基本类型之一;const 命令声明的变量,则被推断为值类型常量。

TS 复制代码
// 类型推断为基本类型 string
let s1 = 'JavaScript';

// 类型推断为字符串 "JavaScript"
const s2 = 'JavaScript';

有些时候,let 变量会出现一些意想不到的报错,变更成 const 变量就能消除报错。

TS 复制代码
let s = 'JavaScript';

type Lang =
  |'JavaScript'
  |'TypeScript'
  |'Python';

function setLang(language:Lang) {
  /* ... */
}

setLang(s); // 报错

在上面例子中,函数setLang()的参数language类型是Lang,这是一个联合类型。但是,传入的字符串s的类型被推断为string,属于Lang的父类型。父类型不能替代子类型,导致报错。

解决方法就是把 let 命令改成 const 命令。

TS 复制代码
const s = 'JavaScript';

这样的话,变量s的类型就是值类型JavaScript,它是联合类型Lang的子类型,传入函数setLang()就不会报错。

除了改成const 命令之外,TS提供了一种特殊的类型断言as const,用于告诉编译器,推断类型时,可以将这个值推断为常量。

TS 复制代码
let s = 'JavaScript' as const;
setLang(s);  // 正确

注意:使用了as const断言以后,let 变量就不能再改变值了。

TS 复制代码
let s = 'JavaScript' as const;
s = 'Python'; // 报错
相关推荐
IT_陈寒38 分钟前
SpringBoot项目启动慢?5个技巧让你的应用秒级响应!
前端·人工智能·后端
树上有只程序猿1 小时前
2026低代码选型指南,主流低代码开发平台排名出炉
前端·后端
橙某人1 小时前
LogicFlow 小地图性能优化:从「实时克隆」到「占位缩略块」!🚀
前端·javascript·vue.js
高端章鱼哥2 小时前
为什么说用OpenClaw对打工人来说“不划算”
前端·后端
大脸怪2 小时前
告别 F12!前端开发者必备:一键管理 localStorage / Cookie / SessionStorage 神器
前端·后端·浏览器
Mr_Mao2 小时前
我受够了混乱的 API 代码,所以我写了个框架
前端·api
小徐_23332 小时前
向日葵 x AI:把远程控制封装成 MCP,让 AI 替我远程控制设备
前端·人工智能
冴羽2 小时前
来自顶级大佬 TypeScript 之父的 7 个启示
前端·typescript
leafyyuki2 小时前
在 Vue 项目中玩转 FullCalendar:从零搭建可交互的事件日历
前端·javascript·vue.js
决斗小饼干2 小时前
低代码平台工作流引擎设计:从状态机到智能流转的技术演进
前端·低代码·工作流引擎