Redian新闻
>
为什么你非常不适应 TypeScript

为什么你非常不适应 TypeScript

公众号新闻

前言

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

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

引子

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

垃圾 TypeScript

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

declare function pick(target: any, ...keys: any): any

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

pick(undefined'a'1).b

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

刚学 TypeScript

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

declare function pick(target: Record<string, unknown>, ...keys: string[]): unknown

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

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

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

不就 TypeScript

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

declare function pick<
  T extends Record<stringunknown>
>(target: T, ...keys: (keyof T)[]): unknown

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

pick({ abcdefghijkl: '123' }, 'abcdefghijkl').abcdefghikjl
  • 一点小小的拓展

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

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

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

算算 TypeScript

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

declare function pick<
  T extends Record<stringunknown>,
  Keys extends keyof T
>(target: T, ...keys: Keys[]): 
{
  [K in Keys]: T[K]
}

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

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

完美 TypeScript

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

export type L2T<L, LAlias = L, LAlias2 = L> = [L] extends [never]
  ? []
  : L extends infer LItem
    ? [LItem?, ...L2T<Exclude<LAlias2, LItem>, LAlias>]
    : never

declare function pick<
  T extends Record<stringunknown>,
  Keys extends L2T<keyof T>
>(target: T, ...keys: Keys): Pick<TKeys[number] & keyof T>

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

const x1 = pick({ a: '1', b: '2' }, 'a', 'a')
//                                  ^^^^^^^^
// TS2345Argument of type '["a", "a"]' is not assignable to parameter of type '["a"?, "b"?] | ["b"?, "a"?]'.
//   Type '["a", "a"]' is not assignable to type '["a"?, "b"?]'.
//     Type at position 1 in source is not compatible with type at position 1 in target.
//       Type '"a"' is not assignable to type '"b"'.

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

总结

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

  • 看到大佬们都在玩,所以自己也想来“玩”,然后为了过类型校验而去写
  • 看到一些成熟的项目在使用 TypeScript ,想参与贡献,参与过程中为了让类型通过而想办法去解决类型报错
  • 公司整体技术栈采用的是 TypeScript ,要用 TypeScript 进行业务编写,从而为了过类型检查和 review 而去解决类型问题

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

  • 类型检查到位
  • 类型提示友好
  • 类型检查严格
  • 扩展性十足

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

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

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

(版权归原作者所有,侵删)


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
普通家庭跟风补课是非常不靠谱的一件事情TypeScript刚刚流行起来,为什么大牛们就开始抛弃了?C# 和 TypeScript 之父亲自带队开源 TypeChat,又一 AI 技术瓶颈被攻破?医院看病,至少中国跟美国一样好iPhone将放弃lighting接口,全面拥抱Type-C小米一开源项目被批“三无”,项目导师回应;Ruby on Rails之父将TypeScript从Turbo框架中移除 | Q资讯[汽车] HONDA Civic Type -R/FL5心理学家贺岭峰炮轰当代父母:你们非常不合格, 拖了孩子后腿!有的医院给医护人员大幅降薪?若属实非常不应该微软开源TypeChat库,给大语言模型换种提示,一行代码安装网坛帅哥常青树————德约科维奇冷却的不止季节(77)— 堵心之事TypeScript 被放弃!又一知名前端利器决意转回JS,社区不满:这在开倒车!产品推荐 | 推荐一款Type-C充电接口的小巧平价剃须刀不要小看这次的吹哨Popstar Jay Chou’s Fans Fume as Scalpers Cash in on Concert HypeTypisch deutsch! 那些只会在德国发生的事...晶圆代工,成熟制程非常不妙Chinese Creepy Crawlies: Keeping the Pests of May at Bay“根本不需要TypeScript,JS+JSDoc够了”,大佬说我想多了关于iPhone 15的Type C接口,这篇值得阅读收藏韩国高官:这事非常不妥!BB鸭 | 特斯拉再降4.5万;AirPods被曝换用Type-C接口;问界M5标准版发布;比亚迪海豚巴西热销Young Chinese Obsess Over MBTI, the American Personality TestZodiac Signs, Height, Blood Type: Absurd Hiring Rules Draw Fire重磅!美国遣返新规不适应中国走线客!润美走线借道南美,边防人员疲于应对…体积减小20%,TypeScript的npm包逐渐变小Henan City Rolls Out Monthly Business Enforcement Amnesty重磅!美国遣返新规不适应中国走线客!中国人润美走线借道南美,这国边防人员疲于应对刚刚发布的iPhone15系列,除了5999和Type-C还有哪些惊喜?[汽车] 还了一个车企对大学生的尊敬,终于与你再遇——捷豹F-type5.0 V8女子称非常不安!BC这城市市中心附近灰熊漫游西方不适应中国变强了冬天里的一把火Anytype:一款用于工作和生产力的一体化安全开源应用 | Linux 中国
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。