Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript中的参数是否可能是错误的类型?_Typescript - Fatal编程技术网

TypeScript中的参数是否可能是错误的类型?

TypeScript中的参数是否可能是错误的类型?,typescript,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 clause

在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
}
我喜欢用guard子句验证输入。所以在JavaScript中,我会测试
mybar
Bar
的一个实例,如果不是,我会抛出一个
TypeError

在TypeScript中,
mybar
是否保证为正确的类型?(从而消除了对第一保护条款的需要)


更新

下面有几个很好的答案,从“绝对可能”到“可能发生”到“不可能发生”


因此,也许一个表达问题的好方法是——如果可能在运行时提供了错误的类型,那么发生这种情况的机制是什么?例如,类型转换中的一个错误?

在TypeScript中的工作方式与JavaScript不同,使用TypeScript时,如果您传递的参数不是函数签名中指定的类型,则在编译过程中会出错,因此您必须遵循函数参数的确切类型。

这取决于您的函数。如果它是一个私有函数,只有您有权访问它,那么TS可以帮助确保它在编译时始终是正确的类型。如果它是一个公共功能,应该由另一个用户/方使用,那么如果您希望具有一定的弹性,则需要进行检查


TS类型是关于设计你的软件,不管你设计得有多好,如果用户选择以错误的方式持有它,它就会崩溃。因此,只在少数公共场所公开,并在那里进行检查。

instanceof
是一项测试,测试对象是否是
条码的实例。这意味着参数的类型也是
Bar
,反之则不一定正确。Typescript使用结构类型,因此任何具有
Bar
结构的对象都将与函数参数兼容。因此,该代码完全有效:

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

class Bar {
    private bar: number;
}
function doSomething(p: Bar) { }
doSomething({ // error now
    bar: 10
})
doSomething({ // breaking out of type safety
    bar: 10
} as any)
如果您的代码库不完全是TS,那么任何类型的安全性都会消失,JS可以随意调用您的TS函数


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

要回答您更新的问题:

如果在运行时可能提供了错误的类型,那么 发生这种情况的机制是什么?计算机打字中的一个错误 例子

有几种方法可以实现:

  • doSomething
    是从JavaScript文件调用的(没有
    checkJs
    @ts check
  • 提供了一个类似于
    Bar
    的对象。它在结构上是相同的,但它不是
    Bar
    的实例
  • 另一个开发人员将类型不正确的参数强制转换为
    Bar
  • 类型不正确的参数被自动强制转换为
    any
    (缺少类型定义,类型推断丢失)
  • 错误类型的参数被写得不好的类型保护程序断言为
    Bar
  • 不正确类型的参数被视为
    Bar
    ,因为它的定义在项目中的其他地方被扩充了
  • 您的代码是在没有构建管道的环境中发布和使用的,因此不可能存在编译时错误(例如,作为UMD包分发)
  • 使用不存在的键对对象或数组进行了索引(TypeScript假定它永远不能是
    未定义的
  • 在混合中使用了标准库中有问题的类型部分(例如,
    Promise.resolve.call(1)
    将在运行时抛出,即使TypeScript接受它)

是和否。您不能保证代码的来世。linter/hinter和transpiler将检查您的类型,但在运行时没有任何东西会执行相同的操作。但是正如上面@ZorgoZ所解释的,在运行时代码仍然会出现错误行为?或者这永远不会发生吗?@Ionix我自己已经使用TS超过4年了,从未遇到过任何代码行为错误的情况,即使在函数定义中指定了参数类型。:)这听起来像是专家的建议,所以我谢谢你!:-)好建议。然而,如果该公共代码也是由我编写的,并且也通过ts transpiler,那么如何能够提供错误的类型呢?发生这种事情的机制是什么?那么你不需要重复检查,你只需要学习信任TS,就像你编写的函数一样。你的答案是好的,值得赞赏,但被接受的答案深入解释了潜在的技术细节。如果我必须诚实的话,我觉得答案离题了。但有些细微差别我不知道,所以我可能是错的。很高兴你通过这个网站发现了很多有用的东西,但QI没有意识到有这么多场景…非常彻底,非常感谢,谢谢!我将继续使用一个保护条款来确保安全。但是作为一个JavaScript开发人员,我遇到了同样的问题。如果没有对函数参数进行类型检查,typescript将无法在运行时抛出错误。在为类似情况编写单元测试时,ts编译器在测试文件中对我大喊大叫,说我传递了一个无效的参数,我故意这样做是为了抛出一个错误。处理这个问题的“打字脚本”方式是什么?是的,“和任何人一样”获救,但我觉得这有点骇人。