在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中,我将测试mybar
是Bar
的实例,如果不是,则抛出TypeError
。
在TypeScript中是否保证mybar
是正确的类型? (从而消除了对第一个保护子句的需要)
更新
下面有一些很好的答案,范围从“肯定有可能”到“可能发生”到“它不可能发生”。
所以表达这个问题的一个好方法是-如果在运行时提供错误的类型,那么发生这种情况的机制是什么?例如类型转换中的错误?
答案 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文件中调用的(没有doSomething
或checkJs
)@ts-check
的对象。在结构上相同,但不是Bar
的实例。Bar
Bar
(缺少类型定义,类型推断会丢失)any
Bar
,因为其定义在项目的其他地方得到了补充Bar
)undefined
即使在TypeScript接受的情况下也会在运行时抛出)答案 3 :(得分:1)
TypeScript与JavaScript的工作原理不同,使用TypeScript,如果您传递函数签名中指定以外的任何其他类型的参数,则编译期间会出错,因此您必须遵循函数参数的确切类型。