阅读 1322

在vue3🔥源码中学会typescript🦕 - "is"

vue3🔥是用typescript实现的, 所以我认为他的源码是我们学习tyepscript的最佳实践, 下面我就用他源码中的实例让大家学会使用typescript的"is"特性.

直达

第一课, 体验typescript

第二课, 基础类型和入门高级类型

第三课, 泛型

第四课, 解读高级类型

第五课, 命名空间(namespace)是什么

特别篇, 在vue3🔥源码中学会typescript🦕 - "is"

第六课, 什么是声明文件(declare)? 🦕 - 全局声明篇

"is"用在什么地方?

我先说用在什么地方, 经常用来封装"类型判断函数", 这类函数都必须用"is"特性, 这类函数一般起名都会叫isString/isFood/isVnode等等, 比如:

const isString = (val: any): val is string => typeof val === 'string'
复制代码

概念

是一种类型推断表达式的关键字, 通过和函数返回值的比较, 从而"缩小"参数的类型范围.

😠看完这句话 "没明白就对了" , 想理解这句话什么意思, 请继续看下面的例子, 😁我保证第一个例子过后你就会明白这句话.

vue在哪里用了"is"

首先教大家一个vscode的小技巧, 搜索中我们可以按"正则"搜索, 比如搜索\): \w+ is我们就可以找到所有使用了"is"特性的代码.

更多常用正则看这里: https://juejin.im/post/5d245d4151882555300feb77

实例解释

从搜索到的代码中, 我们拿出最有代表性的一个函数说明.

const isString = (val: any): val is string => typeof val === 'string'
复制代码

划重点

可以看见在返回值部分返回的不是类型而是一个表达式"val is string", 这段代码的意思是当isString返回值为true的时候, 参数val就是string类型.

直接返回boolean不行吗?

不行! 看下面的代码, 我们虽然知道在if判断后aa一定是string,但是ts不知道, ts会提示aa可能是null类型, 不能执行substring方法.

所以需要使用is特性. ts可以根据 if 判断推断出当前的aastring类型:

更多"is"在vue3中的实例

// 是否是对象
export const isObject = (val: any): val is Record<any, any> =>
  val !== null && typeof val === 'object'

// 是否ref对象
export function isRef(v: any): v is Ref {
  return v ? v[refSymbol] === true : false
}

// 是否vnode
export function isVNode(value: any): value is VNode {
  return value ? value._isVNode === true : false
}

// 是否插槽节点
export const isSlotOutlet = (
  node: RootNode | TemplateChildNode
): node is SlotOutletNode =>
  node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.SLOT
复制代码

更多例子, 可以在源码中搜索\): \w+ is, 大概有16条类似的代码.

通过总结我们发现, "is"主要都是应用在类型判断函数上, 让后续逻辑判断中可以正确的推断出参数的类型, 好了现在可以在回头看开头的解释"is是一种类型推断表达式的关键字, 通过和函数返回值的比较, 从而"缩小"参数的类型范围.", 现在是不是已经理解了呢.

练习

我们自己写一个"判断是否正则表达式"的函数.

🚀答案
function isRegExp (input: any): input is RegExp {
    return '[object RegExp]' === Object.prototype.toString.call(input);
}
复制代码

总结

喜欢ts, 如果你也喜欢ts的话可以看我之前写的ts基础文章.

第一课, 体验typescript

第二课, 基础类型和入门高级类型

第三课, 什么是泛型?

第四课, 解读高级类型

第五课, 命名空间(namespace)是什么?

平时还请大家多多练习, 祝早日熟练ts, 放2个我用ts写的项目当做参考, 抛砖引玉, 加油!

✋ 移动/pc端手势库, 支持: tap/press/pan/swipe/rotate/pinch github.com/any86/any-t…

🍭 把vue组件变成this.$xxx这样的命令 github.com/any86/vue-c…

微信群

感谢大家的阅读, 如有疑问可以加我微信, 我拉你进入微信群(由于腾讯对微信群的100人限制, 超过100人后必须由群成员拉入)

关注下面的标签,发现更多相似文章
评论