当前位置:网站首页>TypeScript中的类型断言
TypeScript中的类型断言
2022-07-26 20:31:00 【混沌前端(微信公众号)】
TypeScript 的类型断言看起来概念比较简单,但是对于刚接触 TypeScript 的使用者,可能对使用场景缺少认识,希望本文可以帮助你更了解类型断言。
当你使用一个值,但是 TypeScript 不知道具体类型 或者 TypeScript 记录的类型没有办法满足使用要求时,可以使用类型断言来明确指定为自己想要使用的类型。
语法:
类型断言有两种方式:
使用 <>语法使用 as关键字
<> 会和 JSX 语法冲突,一般使用 as 。
我们来看几个类型断言的示例
1.对于通过标签获取的DOM,TypeScript可以推断出类型,但是对于其他方式,TypeScript无法推断,我们可以使用类型断言来明确指定元素类型。
const aEle = document.querySelector('a') // HTMLAnchorElement | null
const canvasEle = document.querySelector('#my_canvas') as HTMLCanvasElement
React.useEffect(() => {
if (props.autoFocus) {
const $this = ref.current as HTMLInputElement;
...
}
}, []);
AntD中的示例:ActionButton.tsx
2.对于空对象占位,可以断言为特定类型,以获取正确的代码提示和类型推断
const [user, setUser] = useState<User | null>(null);
setUser(newUser);
const [user, setUser] = useState<User>({} as User);
setUser(newUser);
const 断言
const 断言告诉编译器为表达式推断出它能推断出的最窄或最特定的类型,而不是通用类型。
// point变成一个readonly 数组类型,修改数组内容会提示错误。
let point = [3, 4] as const; // readonly [3, 4]
point[0] = 1 // Error
我们来看一个代码示例:
function useDarkMode() {
const [mode, setMode] = React.useState<'dark' | 'light'>(() => {
// ...
return 'light'
})
...
return [mode, setMode] as const
}
const [mode, setMode] = useDarkMode() // 伪代码,hook需要再函数组件中使用
我们来对比一下 mode 和 setMode 使用 as const 之后的差别:
在使用 const 断言之前,mode 和 setMode 类型为:
const mode: "dark" | "light" | React.Dispatch<React.SetStateAction<"dark" | "light">>
const setMode: "dark" | "light" | React.Dispatch<React.SetStateAction<"dark" | "light">>

调用setMode时,会提示错误,因为 'dark' | 'light' 并不是可调用类型。

使用 as const 断言之后,mode 和 setMode 类型为:
const mode: "dark" | "light"
const setMode: React.Dispatch<React.SetStateAction<"dark" | "light">>


调用传参错误时,也会有类型错误提示。

可以看到,对于数组来说,每个元素的类型是整个数组元素类型的联合类型
const arr = [1,'2']
// const arr: (string | number)[]
使用 as const 断言之后,数组会变成 readonly 数组且每个元素有了自己的特定类型,也有了更好的错误提示。
再来看一个 rxjs 中的示例:fromEvent.ts
// These constants are used to create handler registry functions using array mapping below.
// 这些常量用于使用下面的数组映射创建处理程序注册表函数
const nodeEventEmitterMethods = ['addListener', 'removeListener'] as const;
const eventTargetMethods = ['addEventListener', 'removeEventListener'] as const;
const jqueryMethods = ['on', 'off'] as const;
使用 as const之后,类型检测更为严格:
readonly 数组,每个元素都有自己的字面量类型,无法调整为其他值,杜绝被意外修改的可能 在访问数组元素或进行数组解构时,因数组长度固定,避免越界,更不容易出错
const 断言和 typeof 搭配使用:useSelection.tsx
字符串使用 as const 之后,变量就有了字面量类型,typeof 操作符可以提取其字面量类型使用。
export const SELECTION_ALL = 'SELECT_ALL' as const;
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
export type INTERNAL_SELECTION_ITEM =
| SelectionItem
| typeof SELECTION_ALL
| typeof SELECTION_INVERT;
规避类型检查
TypeScript 只允许类型断言为一个更具体或者更不具体的类型,这个规则可以阻止一些错误的强制类型转换:
const x = "hello" as number;
// Error:将 'string' 类型转换为 'number' 类型可能是一个错误,因为这两种类型都没有充分重叠。如果这是故意的,请先将表达式转换为“unknown”。
我们再来看一个 Antd 中的使用示例: back-top
React.useEffect(() => {
bindScrollEvent();
return () => {
if (scrollEvent.current) {
scrollEvent.current.remove();
}
(handleScroll as any).cancel();
};
}, [props.target]);
handleScroll 是一个函数,但是其他文件中被增加了 cancel 属性,此处直接调用 cancel 方法, TypeScript会提示错误,可以断言为 any 来规避 TypeScript 的类型检查
双重断言
对于我们已经明确的变量类型,如果不存在重叠,可以先断言为一个宽泛的类型(any、unknown),再断言为一个具体的类型。
// es default export should use const instead of let
const ExportTypography = (RefTypography as unknown) as React.FC<TypographyProps>;
注意:当使用断言时,应该确保你了解当前值的类型,避免出错。对于可以收窄的类型,尽量使用类型收窄而非断言。
边栏推荐
- Explain the 190 secondary compiler (decoding table) module of SMR laminated hard disk of Western data in detail
- conda报错:json.decoder.JSONDecodeError:
- Error in render: “TypeError: data.slice is not a function“
- 2022-7-26 第七组 抽象和接口
- 洛谷-线段覆盖-(区间排序问题总结)
- 2022-7-26 the seventh group of abstractions and interfaces
- 没有网络怎么配置传奇SF登陆器自动读取列表
- How to implement Devops with automation tools | including low code and Devops application practice
- 25张炫酷交互图表,一文入门Plotly
- 【HarmonyOS议题资料下载】HDD杭州站·线下沙龙专注应用创新 展现鸿蒙生态魅力
猜你喜欢

SPI配置
![[question] browser get request with token](/img/95/f0b7186f930c014495414c3fcdaa6e.png)
[question] browser get request with token

牛客刷题——Mysql系列

留存收益率计算公式

golang版本管理gvm

Devsecops, speed and security

What is the function of the serializable interface?

Flash source code outline

JVM learning - memory structure - program counter & virtual machine stack & local method stack & heap & method area
![[MySQL series] - how much do you know about the index](/img/d7/5045a846580be106e2bf16d7b30581.png)
[MySQL series] - how much do you know about the index
随机推荐
Leetcode linked list problem - 19. Delete the penultimate node of the linked list (learn the linked list with one question and one article)
JDBC connection
Why does it system need observability?
Relevant contents about wireless communication
Web3.0 时代,基于P2PDB实现一款Dapp的技术理论
2022开放原子全球开源峰会议程速递 | 7 月 27 日分论坛议程一览
如何在一个项目中使用多种不同的语言?
Niuke multi school -journey- (map building distra+ card often optimization)
关于:获取当前客户端登录的域控
微信支付的分账功能介绍
PLSQL package
[HCIA security] user authentication
串口通信失败
Browser browser cache
[hero planet July training leetcode problem solving daily] 26th and check the collection
[OBS] solve the problem of OBS pushing two RTMP streams + timestamp
Daily practice ----- there is a group of students' grades. Arrange them in descending order. To add a student's grade, insert it into the grade sequence and keep the descending order
Svn uses fragmented ideas
08_ UE4 advanced_ Start end pause menu UI
flask 源码梗概