1 Star 0 Fork 13

xiang/grammarLearning

forked from 韩旭明/grammarLearning 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
11_类型工具_9、类型守卫:is.ts 3.41 KB
一键复制 编辑 原始数据 按行查看 历史
韩旭明 提交于 2023-01-27 16:56 . 修改说明
/**
* TypeScript 中提供了非常强大的类型推导能力,
* 它会随着你的 代码逻辑 不断尝试收窄类型,
* 这一能力称之为 类型的控制流分析(也可以简单理解为 类型推导 )。
*/
/**
* 比如,通过 if 条件中的表达式进行了类型保护,即告知了这里的分析程序 每个 if 语句代码块中变量会是何类型。
* 这即是 编程语言的类型能力 中最重要的一部分:
* 与实际逻辑紧密关联的类型,从 逻辑 中进行 类型地推导,再反过来让 类型 为 逻辑 保驾护航
*/
function foo(input: string | number) {
if (typeof input === 'string') { }
if (typeof input === 'number') { }
// ...
}
/**
* 但是,如果 if 条件中的表达式要是现在被提取出来了。
* 因为 isString 这个函数在另外一个地方,内部的判断逻辑并不在函数 foo 中。
* TypeScript的 类型控制流分析 做不到 跨函数上下文 来进行 类型的信息收集(但别的类型语言中可能是支持的)。
* */
function isString(input: unknown): boolean {
return typeof input === "string";
}
function fooA(input: string | number) {
if (isString(input)) {
// 类型“string | number”上不存在属性“replace”。
(input).replace("hanxuming", "hanxuming599")
}
if (typeof input === 'number') { }
// ...
}
/**
* 实际上,将判断逻辑封装起来提取到函数外部进行复用非常常见
* 为了解决这一类型控制流分析的能力不足, TypeScript 引入了 is 关键字来显式地提供类型信息:
*
* isString 函数称为类型守卫,在它的返回值中,不再使用 boolean 作为类型标注,
* 而是使用 input is string 这样的搭配,其中:
* input 函数的某个参数;
* is string,即 is 关键字 + 预期类型,
* 即如果这个函数成功返回为 true,
* 那么 is 关键字前这个入参的类型,就会被这个 类型守卫调用方 后续的 类型控制流分析 收集到。
*/
function isStringA(input: unknown): input is string {
return typeof input === "string";
}
function fooB(input: string | number) {
if (isStringA(input)) {
// 正确了
(input).replace("hanxuming", "hanxuming599")
}
if (typeof input === 'number') { }
// ...
}
/**
* 需要注意的是,类型守卫函数中并不会对判断逻辑和实际类型的关联进行检查:
*
* 从这个角度来看,其实 类型守卫 有些类似于 类型断言,但类型守卫更宽容,也更信任你一些。
* 你指定什么类型,它就是什么类型。
*/
function fooC(input: string | number) {
if (isStringA(input)) {
// 报错,在这里变成了 number 类型
(input).replace("hanxuming", "hanxuming599")
}
if (typeof input === 'number') { }
// ...
}
/**
* 除了使用简单的原始类型以外,还可以在类型守卫中使用对象类型、联合类型等,
* 比如下面开发时常用的两个守卫:
*/
export type Falsy = false | "" | 0 | null | undefined;
export const isFalsy = (val: unknown): val is Falsy => !val;
//不包括不常用的 symbol 和 bigint
export type Primitive = string | number | boolean | undefined;
export const isPrimitive = (val: unknown): val is Primitive => ['string', 'number', 'boolean' , 'undefined'].includes(typeof val);
//export {}:解决“无法重新声明块范围变量”错误提示问题
export { }
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/liaozhixiang/grammar-learning.git
git@gitee.com:liaozhixiang/grammar-learning.git
liaozhixiang
grammar-learning
grammarLearning
master

搜索帮助