0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么你根本学不下去TypeScript?

马哥Linux运维 来源:稀土掘金 作者:一介4188 2023-08-11 10:12 次阅读

前言

在群里看到一些问题和言论:为什么你们这么喜欢“类型体操”?为什么我根本学不下去 TypeScript?我最讨厌那些做类型体操的了;为什么我学了没过多久马上又忘了?

有感于这些问题,我想从最简单的一个角度来切入介绍一下 TypeScript,并向大家介绍并不是只要是个类型运算就是体操。并在文中介绍一种基本思想作为你使用类型系统的基本指引。

引子

我将从一个相对简单的 API 的设计过程中阐述关于类型的故事。在这里我们可以假设我们现在是一个工具的开发者,然后我们需要设计一个 API 用于从对象中拿取指定的一些 key 作为一个新的对象返回给外面使用。

垃圾 TypeScript

一个人说:我才不用什么破类型,我写代码就是要没有类型,我就是要随心所欲的写。然后写下了这段代码。

declarefunctionpick(target:any,...keys:any):any

他的用户默默的写下了这段代码:

pick(undefined,'a',1).b

写完运行,发现问题大条了,控制台一堆报错,接口数据也提交不上去了,怎么办呢?

刚学 TypeScript

一个人说:稍微检查一下传入类型就好了,别让人给我乱传参数就行。

declarefunctionpick(target:Record,...keys:string[]):unknown

很好,上面的问题便不复存在了,API 也是基本可用的了。但是!当对象复杂的时候,以及字段并不是短单词长度的时候就会发现了一个没解决的问题。

pick({abcdefghijkl:'123'},'abcdefghikjl')

从肉眼角度上,我们很难发现这前后的不一致,所以我们为什么要让调用方的用户自己去 check 自己的字段有没有写对呢?

不就 TypeScript

一个人说:这还不简单,用个泛型加 keyof 不就行了。

declarefunctionpick<
  T extends Record
>(target:T,...keys:(keyofT)[]):unknown

我们又进一步解决的上面的问题,但是!还是有着相似的问题,虽然我们不用检查 keys 是不是传入的是一个正确的值了,但是我们实际上对返回的值也存在一个类似的问题。

pick({abcdefghijkl:'123'},'abcdefghijkl').abcdefghikjl

一点小小的拓展

在这里我们看起来似乎是一个很简单的功能,但实际上蕴含着一个比较重要的信息

为什么我们之前的方式都拿不到用户传入进来的类型信息呢?是有原因的,当我们设计的 API 的时候,前面的角度是从,如何校验类型方向进行的思考。

而这里是尝试去通过约定好的一种规则,通过 TypeScript 的隐式类型推断获得到传入的类型,再通过约定的规则转化出一种新的类型约束来对用户的输入进行限制。

算算 TypeScript

一个人说:好办,算出来一个新的类型就好了。

declarefunctionpick<
  T extends Record,
KeysextendskeyofT
>(target:T,...keys:Keys[]):{
[KinKeys]:T[K]
}

到这里已经是对类型的作用有了基础的了解了,能写出来符合开发者所能接受的类型相对友好的代码了。我们可以再来思考一些更特殊的情况:

//输入了重复的key
pick({a:''},'a','a')

完美 TypeScript

到这里,我们便是初步开始了类型“体操”。但是在本篇里,我们不去分析它。

exporttypeL2T=[L]extends[never]
?[]
:LextendsinferLItem
?[LItem?,...L2T,LAlias>]
:never

declarefunctionpick<
  T extends Record,
KeysextendsL2T
>(target:T,...keys:Keys):Pick

constx0=pick({a:'1',b:'2'},'a')
console.log(x0.a)
//@ts-expect-error
console.log(x0.b)

constx1=pick({a:'1',b:'2'},'a','a')
//^^^^^^^^
//TS2345:Argumentoftype'["a","a"]'isnotassignabletoparameteroftype'["a"?,"b"?]|["b"?,"a"?]'.
//Type'["a","a"]'isnotassignabletotype'["a"?,"b"?]'.
//Typeatposition1insourceisnotcompatiblewithtypeatposition1intarget.
//Type'"a"'isnotassignabletotype'"b"'.

一个相对来说比较完美的 pick 函数便完成了。

总结

我们再来回到我们的标题吧,从我对大多数人的观察来说,很多的人开始来使用 TypeScript 有几种原因:

看到大佬们都在玩,所以自己也想来“玩”,然后为了过类型校验而去写

看到一些成熟的项目在使用 TypeScript ,想参与贡献,参与过程中为了让类型通过而想办法去解决类型报错

公司整体技术栈采用的是 TypeScript ,要用 TypeScript 进行业务编写,从而为了过类型检查和 review 而去解决类型问题

诸如此类的问题还有很多,我将这种都划分为「为了解决类型检查的问题」而进行的类型编程,这也是大多数人为什么非常不适应 TypeScript,甚至不喜欢他的一个原因。这其实对学习 TypeScript 并不是一个很好的思路,在这里我觉得我们需要站在设计者的角度去对类型系统进行思考。我觉得有以下几个角度:

类型检查到位

类型提示友好

类型检查严格

扩展性十足

我们如果站在这几个角度对我们的 API 进行设计,我们可以发现,开发者能够很轻松的将他们需要的代码编写出来,而尽量不用去翻阅文档,查找 example。

希望通过我的这篇分享,大家能对 TypeScript 多一些理解,并参与到生态中来,守护我们的 JavaScript。

链接:https://juejin.cn/post/7248599585751515173





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA语言
    +关注

    关注

    0

    文章

    138

    浏览量

    20090
  • javascript
    +关注

    关注

    0

    文章

    516

    浏览量

    53850
  • java接口
    +关注

    关注

    0

    文章

    2

    浏览量

    1165

原文标题:为什么你非常不适应 TypeScript

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    使用DAC3484+TRF3705,测试发现调制出来的射频150M左右底噪很高怎么解决?

    各位TI专家,最近使用DAC3484+TRF3705,测试发现调制出来的射频150M左右底噪很高,目前确认是模拟IQ信号带来的,但是无论怎么调试都降不下去,目前将进行改板设计,心理没底,毕竟成本
    发表于 12-03 07:03

    ESP32 深度睡眠

    使用的是ESP32S2 idf 5.2.2 官方代码历程deep_sleep 进入深度睡眠 睡眠后功耗为1.9mA,一直降不下去
    发表于 07-11 09:50

    RT-THREAD studio生成的工程,晶振不起振是怎么回事?

    最近用rt-thread studio 生成了一个stm32f103zet6得工程,用cubemx setting生成了时钟,如下图所示: 结果发现代码跑到这里就跑不下去了 后来发现会一直
    发表于 07-11 06:45

    ESP32S2最小模块,采用官方例子进入深度睡眠,功耗为什么降不到和官方手册一致

    使用的是ESP32S2 idf 5.2.2 官方代码历程deep_sleep 进入深度睡眠 睡眠后功耗为1.9mA,一直降不下去
    发表于 07-10 18:02

    鸿蒙开发:【从TypeScript到ArkTS的适配规则】

    ArkTS通过规范约束了TypeScript(简称TS)中过于灵活而影响开发正确性或者给运行时带来不必要额外开销的特性
    的头像 发表于 05-14 09:37 1957次阅读
    鸿蒙开发:【从<b class='flag-5'>TypeScript</b>到ArkTS的适配规则】

    STM8L052在主函数while电流900ua加一句halt电流210ua怎么都调不下去的原因?

    画了一块板子,只焊了复位电路在主函数while 电流900ua加一句 halt电流 210ua 怎么都调不下去请问大家 是不是哪里出错了,res管脚为上拉输入 其他都是浮空输入。。为什么跟标准的差这么多...
    发表于 05-13 08:14

    不小心把SWIM引脚设置成了out,结果修改的程序怎么也下载不下去了,芯片是不是报废了?

    犯了个低级错误,不小心把SWIM引脚设置成了out,结果修改的程序怎么也下载不下去了,STVP还是内嵌的programmer均显示连接设备了。不知道是不是有其他方法?还是这块芯片就报废了呢?
    发表于 04-22 07:24

    鸿蒙TypeScript学习21天:【声明文件】

    TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。
    的头像 发表于 04-19 15:02 577次阅读
    鸿蒙<b class='flag-5'>TypeScript</b>学习21天:【声明文件】

    鸿蒙TypeScript学习第20天:【模块】

    TypeScript 模块的设计理念是可以更换的组织代码。 模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。
    的头像 发表于 04-18 15:19 714次阅读
    鸿蒙<b class='flag-5'>TypeScript</b>学习第20天:【模块】

    鸿蒙语言TypeScript学习第16天:【类】

    TypeScript 支持面向对象的所有特性,比如 类、接口等。
    的头像 发表于 04-15 09:29 1011次阅读
    鸿蒙语言<b class='flag-5'>TypeScript</b>学习第16天:【类】

    鸿蒙TypeScript 开发学习第9天:【TypeScript Number】

    TypeScript 与 JavaScript 类似,支持 Number 对象。 Number 对象是原始数值的包装对象。
    的头像 发表于 04-07 18:02 783次阅读
    鸿蒙<b class='flag-5'>TypeScript</b> 开发学习第9天:【<b class='flag-5'>TypeScript</b> Number】

    鸿蒙TypeScript入门学习第6天:【条件语句】

    条件语句用于基于不同的条件来执行不同的动作。 TypeScript 条件语句是通过一条或多条语句的执行结果(True 或 False)来决定执行的代码块。
    的头像 发表于 04-01 13:51 751次阅读
    鸿蒙<b class='flag-5'>TypeScript</b>入门学习第6天:【条件语句】

    鸿蒙TypeScript开发入门学习第3天:【TS基础类型】

    任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型,它常用于以下三种情况。
    的头像 发表于 03-28 15:02 531次阅读
    鸿蒙<b class='flag-5'>TypeScript</b>开发入门学习第3天:【TS基础类型】

    鸿蒙TypeScript入门学习第2天【TypeScript安装】

    本文介绍 TypeScript 环境的安装。 我们需要使用到 npm 工具安装,如果还不了解 npm,可以参考我之前文档。
    的头像 发表于 03-27 15:22 503次阅读
    鸿蒙<b class='flag-5'>TypeScript</b>入门学习第2天【<b class='flag-5'>TypeScript</b>安装】

    E203用iverilog12仿真时,run_test一直卡怎么解决?

    求助!!一直卡在这里进行不下去了,请问大佬们这是为什么呀?每个步骤都是按照教程来的!iverilog用的12,ubuntu 20.04
    发表于 01-10 07:07