在TypeScript中,参数的类型是否曾经错误?

时间:2019-01-19 11:11:30

标签: typescript

在JavaScript中:

function doSomething(mybar) {
  if (!(mybar instanceof Bar)) throw new TypeError("mybar");
  // ...other guard clauses
}

在TypeScript中:

function doSomething(mybar: Bar) {
  // is guard clause ALWAYS redundant?
  // ...other guard clauses
}

我喜欢使用保护子句来验证输入。因此,在JavaScript中,我将测试mybarBar的实例,如果不是,则抛出TypeError

在TypeScript中是否保证mybar是正确的类型? (从而消除了对第一个保护子句的需要)


更新

下面有一些很好的答案,范围从“肯定有可能”到“可能发生”到“它不可能发生”。

所以表达这个问题的一个好方法是-如果在运行时提供错误的类型,那么发生这种情况的机制是什么?例如类型转换中的错误?

4 个答案:

答案 0 :(得分:2)

这取决于您的功能。如果它是私有函数,则只有您可以访问它,然后TS才能帮助确保它可以编译,始终是正确的类型。如果它是公共功能,应该由其他用户/一方使用,那么如果要具有一定的弹性,则必须进行检查。

TS类型与设计软件有关,如果用户选择以错误的方式持有它,则设计得多么好不重要,它会中断。因此,仅公开几个公共场所,然后在此处进行检查。

答案 1 :(得分:2)

if是测试对象是否为instanceof的实例。尽管这意味着参数的类型也为Bar,但不一定要正确。 Typescript使用结构化类型,因此具有Bar结构的任何对象都将与function参数兼容。因此,此代码完全有效:

Bar

拥有私有属性时,您无法如此轻松地“伪造”对象,但是即使如此,我们也始终可以断言为class Bar { bar: number; } function doSomething(p: Bar) { } doSomething({ bar: 10 })

any

如果您的代码库并非完全是TS,那么任何类型安全性都将无法使用,JS可以随便调用您的TS函数。

这是否意味着您应该始终包括支票?我反对。 JS的类型非常松散(TS也是如此),这就是用户所期望的。如果它像鸭子一样嘎嘎叫,那它就是鸭子,这是旧的JS咒语。如果对象具有可与您的函数一起使用的属性,则无论如何创建,该对象都应与您的函数一起使用。

答案 2 :(得分:2)

要回答您的最新问题:

  

如果有可能在运行时提供了错误的类型,那是什么   发生这种情况的机制?类型转换中的错误   例子吗?

有几种可能的发生方式:

  • product_id是从JavaScript文件中调用的(没有doSomethingcheckJs
  • 提供了类似于@ts-check的对象。在结构上相同,但不是Bar的实例。
  • 另一位开发人员将类型错误的参数强制转换为Bar
  • 类型错误的参数会自动转换为Bar(缺少类型定义,类型推断会丢失)
  • 一个写得不好的类型后卫断言类型错误的自变量为any
  • 类型错误的自变量被视为Bar,因为其定义在项目的其他地方得到了补充
  • 您的代码是在没有构建管道的环境中运输和使用的,因此不会存在编译时错误(例如,作为UMD软件包分发)
  • 使用不存在的键对对象或数组进行了索引(TypeScript假定它永远不能为Bar
  • 混合中使用了标准库的可疑类型部分(例如,undefined即使在TypeScript接受的情况下也会在运行时抛出)

答案 3 :(得分:1)

TypeScript与JavaScript的工作原理不同,使用TypeScript,如果您传递函数签名中指定以外的任何其他类型的参数,则编译期间会出错,因此您必须遵循函数参数的确切类型。