详解Anyscript开发指南绕过typescript类型检查


Posted in Javascript onSeptember 23, 2022

前言

随着越来越多的前端项目采用 typescript 来开发,越来越多前端开发者会接触、使用这门语言。它是前端项目工程化的一个重要帮手,结合 vscode 编辑器,给予了前端开发者更严谨、高效的编码体验。但同时,严格的类型检查也会使部分开发者的编码效率有所降低,将时间花费在解决类型冲突、类型不匹配上,从而导致望而却步,迟迟不敢上手。

本文描述了几种绕过 typescript 类型检查的方法,帮助ts开发者在遇上第三方库类型声明有误、上线时间紧张却还被ts类型耽搁开发进度、以及其他奇奇怪怪ts类型声明的场景时,能够快速摆脱ts类型检测,保障项目尽快上线。

注意,本文所提到的方法,只能作为一种最后不得已的hack手段,其目的是为了尽快完成需求而非代码取巧,读者不应该将其当成一种常用的写法并在项目内任意使用!

场景设定

假设存在一个第三方库,允许开发者通过 json 定义一个表单,其 typescript 类型定义如下:

interface FormItem{
    /** 表单类型 */
    type:string
    /** 显示文本 */
    label:string
}
interface FormSelectItem extends FormItem{  
    /** 将表单类型指定为'select' */
    type:'select'
    /** 新增一个options属性,类型为数组,此类型定义存在错误,没有定义options数组里面的内容 */
    options:[]
}
type FormRule = (FormSelectItem|FormItem)[]

代码里,FormSelectItem.options期望的是一个有内容的数组,但因为第三方库给定的类型文件编写错误,没有给出数组内部项的结构,只留下[]空数组类型定义,导致开发者给FormSelectItem.options赋予一个有内容的数组都会导致 typescript 报错。

详解Anyscript开发指南绕过typescript类型检查

解决方法

注释忽略

//@ts-ignore会让typescript编译器跳过注释下一行代码,不对其进行类型检查。通过不检查类型的方式,绕过类型检查

//@ts-ignore
window.aaaa = "使用示例(ts里不允许通过此行代码往全局对象挂载属性)"

场景用例

详解Anyscript开发指南绕过typescript类型检查

加上//@ts-ignoreoptions属性之上,编译器跳过了options属性的检查,因此报错消失。使用起来十分简单快捷,但是加了注释忽略之后,开发者为options赋予任何值都是合法的,如非数组的对象、null、undefined等容易引起程序出错的类型。同时加了//@ts-ignore之后,编辑器无法再对此行进行代码提示和自动补全。

类型断言

类型断言是typescript中一种将一个类型指定为另一个类型的语法。通过指定任意类型为目标类型的方式,达到编译器不报错的效果。

(window as unknown as {aaa:string}).aaa = "使用示例(ts里不允许通过此行代码往全局对象挂载属性)"

场景用例

详解Anyscript开发指南绕过typescript类型检查

上图使用了断言语法,且用到两种断言方式:

  • 第一种写法是给赋值数据下断言,将数据类型强制断言为定义类型,即在上图中,将{label:string,value:string}[]断言为[],使得能够与options 的类型匹配上。在属性赋值中只能使用此种断言写法。
  • 第二种写法是反过来,通过将定义类型强制断言为数据类型,即在上图中,将[]断言为{label:string,value:string}[],使得select.options能够按照开发者的数据类型进行工作。并且通过此种方式,对select.options进行操作时,编辑器还会根据开发者的断言类型进行语法提示。

相比注释忽略,类型断言原本就是typescript语法的一部分,本身就会接受类型检查,因此后续的代码补全提示功能是完整的。但同时开发者主观上应当明白类型断言的作用,避免将不正确的数据类型传入导致代码出错。

泛型转换

泛型是typescript最强大的功能,它提供给了开发者们对类型“编程”的能力。通过定义泛型辅助函数,在类型断言的基础上,利用函数返回泛型的手段,巧妙地将类型匹配上,从而达到缩小代码量且编译器不报错的效果。

function _any<T>(obj:any):T{
    return obj as unknown as T
}
_any<{aaa:string}>(window).aaa='使用示例(ts里不允许通过此行代码往全局对象挂载属性)'

实际上,辅助函数也只是将参数当作是返回值而已,只不过利用泛型可以指定为任意类型。

甚至可以设置两个泛型:一个是目标泛型,也就是函数要返回的数据类型,一个是参数泛型,也就是传入的数据类型。当显式地赋予泛型P一个类型时,typescript可以为参数提供类型检查和语法补全。

function _any<T,P=any>(obj:P):T{
    return obj as unknown as T
}
const select:FormSelectItem = {
    type:'select',
    options:_any<[],{label:string,value:string}[]>([{
        label:'',
        value:''
    }])
}
_any<{label:string,value:string}[]>(select.options).push({
    label:'',
    value:''
})

场景用例

详解Anyscript开发指南绕过typescript类型检查

相比类型断言,使用泛型转换辅助函数的做法最大的作用,是简化了as unknow as xxx的写法,本质上还是一样的。开发者同样需要明白转类型的作用,避免使用错误的类型导致代码错误。

总结

遇上类型对不上,项目又急着上线,缺乏足够的时间跟typescript编译器慢慢折腾的情况下,可以酌情使用注释忽略、类型断言、泛型转换的方法来强行指定类型。

其中注释忽略是利用编译器跳过的方式,停止类型检查,带来的后果就是该行其他数据无法获得类型校验;

类型断言、泛型转换都通过断言的语法,强行指定类型,使类型对应上,进而通过编译;

而泛型转换是利用辅助函数的写法,来减少断言代码的编写。

但这三种方式都存在风险,开发者都需要明白赋予的数据类型的含义,避免数据错误导致代码出错。

以上就是详解Anyscript开发指南绕过typescript类型检查的详细内容,更多关于Anyscript绕过typescript类型检查的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
jQuery easyui datagrid动态查询数据实例讲解
Feb 26 Javascript
Json序列化和反序列化方法解析
Dec 19 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
javascript实现动态模态绑定grid过程代码
Sep 22 Javascript
轻松掌握JavaScript装饰者模式
Aug 27 Javascript
JavaScript实现经典排序算法之选择排序
Dec 28 Javascript
canvas 弹幕效果(实例分享)
Jan 11 Javascript
Bootstrap3.3.7导航栏下拉菜单鼠标滑过展开效果
Oct 31 Javascript
如何编写一个d.ts文件的步骤详解
Apr 13 Javascript
微信小程序wx:for循环的实例详解
Oct 07 Javascript
vue组件命名和props命名代码详解
Sep 01 Javascript
LayUi数据表格自定义赋值方式
Oct 26 Javascript
js基于div丝滑实现贝塞尔曲线
Sep 23 #Javascript
TS 类型兼容教程示例详解
Sep 23 #Javascript
TS 类型收窄教程示例详解
Sep 23 #Javascript
JavaScript实现简单的音乐播放器
Aug 14 #Javascript
vue实现简易音乐播放器
Aug 14 #Vue.js
Vue3实现简易音乐播放器组件
Aug 14 #Vue.js
element tree树形组件回显数据问题解决
Aug 14 #Javascript
You might like
德生S2000电路分析
2021/03/02 无线电
PHP调用MySQL存储过程并返回值的方法
2014/12/26 PHP
Cygwin中安装PHP方法步骤
2015/07/04 PHP
Apache无法自动跳转却显示目录的解决方法
2020/11/30 PHP
onpropertypchange
2006/07/01 Javascript
限制textbox或textarea输入字符长度的JS代码
2013/10/16 Javascript
Jquery实现的一种常用高亮效果示例代码
2014/01/28 Javascript
JavaScript不使用prototype和new实现继承机制
2014/12/29 Javascript
jQuery实现的fixedMenu下拉菜单效果代码
2015/08/24 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
JS回调函数简单用法示例
2017/02/09 Javascript
js控制按钮,防止频繁点击响应的实例
2017/02/15 Javascript
JavaScript对JSON数据进行排序和搜索
2017/07/24 Javascript
jQuery响应滚动条事件功能示例
2017/10/14 jQuery
Vue实现购物车场景下的应用
2017/11/27 Javascript
bootstrap table合并行数据并居中对齐效果
2018/10/17 Javascript
Vue + Elementui实现多标签页共存的方法
2019/06/12 Javascript
jQuery提示框插件SweetAlert用法分析
2019/08/05 jQuery
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
javascript 函数的暂停和恢复实例详解
2020/04/25 Javascript
Vue通过provide inject实现组件通信
2020/09/03 Javascript
微信小程序用户登录和登录态维护的实现
2020/12/10 Javascript
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
python使用内存zipfile对象在内存中打包文件示例
2014/04/30 Python
Python开发WebService系列教程之REST,web.py,eurasia,Django
2014/06/30 Python
利用python实现数据分析
2017/01/11 Python
python保存数据到本地文件的方法
2018/06/23 Python
Python实现Selenium自动化Page模式
2019/07/14 Python
Python如何使用字符打印照片
2020/01/03 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
培训主管的岗位职责
2013/11/23 职场文书
请假条范文大全
2014/04/10 职场文书
元宵节晚会主持词
2015/07/01 职场文书
电力安全教育培训心得体会
2016/01/11 职场文书
2019新员工心得体会
2019/06/25 职场文书
前端框架ECharts dataset对数据可视化的高级管理
2022/12/24 Javascript