当前位置: 首页 > 知识库问答 >
问题:

关于typescript的一些困惑?

公冶兴文
2023-06-13

1.首先,我想确认一下从编程的角度,我们有“静态类型检查”和“动态类型检查,对把?
2.一般情况下我们用typescript做静态类型检查,检查源码里面自定义数据类型,对把?
3.那么,我们做的所谓的动态类型检查是不是指的那些库,比如Joi,ajv什么的,比如你点击一个按钮,然后调这个库来检查一个obj的schema,如果类面的key value类型都能对的上,我们就通过,如果类型对不上,我们就报错。这个我理解的对把?
4.另外,我想问一下,ts可以做动态类型检查吗?
5.我最大的困惑来自于,那个源码我们是自己写的,为啥ts还这么的重要,用来检查类型?相反,动态的数据是“运行时“来的,也就是,要不是call api的来的,要不是终端用户输入填写的时候来的,这个时候数据的结构才是不确定的,反而没有那么多的人讨论这个,ok,就算你说,有可能这个是一个庞大的项目,有几百个人一起合作,但是我看到useState("")的时候我肯定知道这个type是一个string阿,ts为什么那么重要阿。我看到其他人举例说function的参数,可能有很多很多,如果加上ts,方便知道传什么,不过我感觉这种情况不是很常见,程序员自定义的函数,或者自己去封装,一般都不会搞很多参数进去吧。
6.您觉得静态检查和动态检查哪个更重要,或者说在你的开发生涯中,是静态type报错的多,还是动态报错更常见呢?
7.react自带的那个propTypes库,是动态检查还是静态检查阿?

感谢大佬的回答,如果您能逐一回答yes或者no,来确认我的理解是否准确就更好了。

共有2个答案

东方富
2023-06-13
  1. 对的。
  2. 是吧。
  3. 啊对。
  4. 不可以。
  5. 人容易犯错;动态数据的入口可以控制,代码比例其实相对是更少的。
  6. 静态检查更具备价值。我认为静态检查是静态分析的一部分,代码可以通过静态分析,在执行之前提前暴露错误,给编译器优化空间(举例 tree shaking)等……静态报错的代码一般上不去生产环境,所以就生产环境而言,就只有动态报错了。
  7. 不认识。

用 typescript 可以避免很多编码本身带来的错误,或本问题中重点讨论的类型错误。应用 typescript 后,你只要把控动态数据的入口,使用 class-validator 类似的库,在给那些 "JSON.parse" 而来或未知类型的数据做校验,将动态的数据变成已知类型的数据,就能根绝动态类型报错了。

段干宜
2023-06-13
  1. true。
  2. true。
  3. true。
  4. false。TS 编译之后就成了 JS,即使你编写了对应的逻辑,那也并不能说是 TS 完成的动态类型检查。
  5. 这一点就在于,如果你是一个组件或插件的开发者,提供了 index.d.ts,那么函数如何使用是很明显的。因为我不需要看函数实现的细节,只要告诉我参数几个、类型几何、返回值是什么样就好了。可能说 JSDoc 也可以做到类似的效果,那可以问问自己,平时注释都没写几行的人,还写 JSDoc?我觉得和注释是差不多的,有,当然最好,而且是可以实实在在地提供检查和提示。不然也不会有那么多的 defineConfig() 了。
  6. 静态检查在编码时就能发现一些错误,至于动态检查,就个人而言,如果不是给其它开发者使用的话,这个东西基本是不会写的。写一套良好的动态检查不见得比写 TS 简单,不过兼容性会更好确实是真的(考虑使用者不使用 TS)。
  7. 动态检查。与 Vue Props 类似。但是书写很繁琐,可以使用 TS 代替。为什么会出现这么个东西呢?React 组件说白了也是函数,我怎么知道那个参数可以传什么类型。不是所有库都可以做到像 jQuery 那样,拥有极强的兼容性,一个核心函数打天下太累了,而且 jQuery 是固定的(万众一心),可我使用的组件库可不一定,对于组件开发者来说,使用 propTypes 给使用者提供一些提醒是很不错的。而 TS 和 VSCode 都是在 20 年之后才锋芒毕露,在此之前没有那么好的支持。

当然,这并不能说:无脑用 TypeScript 就可以了!只是给了一种可选的方式而已(Any or Type)。

为第 5 点补充一图,这很直观了。

image.png

 类似资料:
  • TypeScript 的 Truthiness narrowing 有如下介绍: all coerce to false, and other values get coerced to true. You can always coerce values to booleans by running them through the Boolean function, or by using t

  • 当您可以调用递归方法而不是必须将递归方法设置为变量时,是否有一种简单的方法来理解? 例如... 只是调用递归函数遍历: self.recurse(node.left) self.recurse(node.right) 必须将递归函数设置为node。左和右。右: 节点。左=自我。递归(node.left) 节点。右=自我。递归(node.left) 另一个例子是删除bst中的一个节点,你必须将递归函

  • 问题内容: 在Node.js Express模块​​的代码中,我碰到了这一行,为服务器设置继承: 我不确定这样做是什么- MDC文档(https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited#prototype_and_ proto )似乎说我可以这样做: 确实,我做了这个测试: 看起来一样吗?所以,是的,我想知

  • 例如,一个方法中有10000次循环。当它运行1000次时,backedge\u计数器触发JIT编译。解释器继续执行。当它循环4000次时,JIT编译完成。 我的问题是,剩余的6000次是如何由解释器执行的,还是如何执行本机代码?或者在下次调用此方法之前不会执行本机代码?下次调用此方法时会发生什么?

  • 但后者给了我下面的例外。这是为什么? java.lang.StringIndexOutOfBoundsException:String index超出范围:1 java.lang.StringIndexOutOfBoundsException:String index超出范围:1 java.lang.String.charat(String.java:658)在Scala.Collection.i

  • 假设在快速排序的情况下,我们选择一个轴作为数组的第一个元素。现在,最佳/最坏情况的复杂性是,而在平均情况下,它是。是不是很奇怪(最好的情况复杂度大于最坏的情况复杂度)?