Angular Typescript-在运行时检查键入并警告错误
导言 我用的是角度6 Angular使用typescript,因此您可以键入函数的参数:Angular Typescript-在运行时检查键入并警告错误,angular,typescript,Angular,Typescript,导言 我用的是角度6 Angular使用typescript,因此您可以键入函数的参数: public fun1(aaa: number) { console.log(aaa); } 如果我尝试使用其他类型的参数调用fun1,我将得到一个错误: public fun2() { this.fun1([1, 2, 3]); // TS2345: Argument of type 'number[]' is not assignable to parameter of type 'numbe
public fun1(aaa: number) {
console.log(aaa);
}
如果我尝试使用其他类型的参数调用fun1
,我将得到一个错误:
public fun2() {
this.fun1([1, 2, 3]); // TS2345: Argument of type 'number[]' is not assignable to parameter of type 'number'
}
问题
如果我能控制文件中的参数,类型检查就可以很好地工作
但可能是用我从后端获得的一些参数调用了fun1
Typescript在运行时不工作,因此不会显示任何错误,fun1
的代码只需运行[1,2,3]
--编辑--
后端响应不是问题的唯一来源。有时,库可能会更改您的数据类型,而您可能对此一无所知。一个例子是使用带有控件的反应式表单,该控件应该是一个数字——当您编辑数字时,它将转换为字符串
问题
在运行时是否有一些处理类型检查的常用方法
我想到了这样的事情:
public fun1(aaa: number) {
if (typeof aaa !== 'number') {
console.warn('wrong type');
} else {
console.log(aaa);
}
}
,但WebStorm随后告诉我,检查的类型总是错误的:“aaa”总是有类型“number”
同样,在每个函数的顶部添加这样的内容似乎添加了很多不必要的代码
有人对此有好的解决方案吗?TypeScript——按设计——不提供运行时类型信息(请参阅,非目标,第5点) 如果向TypeScript提供一些外部数据(可能是HTML中传入的数据属性或从RESTAPI获取的数据属性),TypeScript将无法知道其类型。但有一些解决办法。我们来看看其中的两个 您可以采取的一种方法是使用
as
操作符绕过类型系统。这不是一种类型安全的方法(您在类型系统中引入了一个漏洞),但它(至少部分)符合TypeScript的目标(请参见上面的链接)
让我们假设fetchApiSync
函数调用只返回一个简单的javascript对象{name:“John”,age:42}
,我们有一个函数:
function introduceMe(person: Person) {
return `My name is ${person.name} and I'm ${person.age} years old.`
}
以及一个接口
interface Person {
name: string;
age: number;
}
现在,让我们执行以下操作:
constperson:person=fetchPersonFromApi(1)代码>
显然,我们希望fetchPersonFromApi
返回一个与Person
接口匹配的值,以便我们可以执行以下操作:
const introduction=introductionme(个人)代码>
为了实现这一目标,我们可以采取以下措施:
function fetchPersonFromApi(id: number): Person {
// it's synchronous and without error handling just for brevity
const response: Person = fetchApiSync(`/persons/${id}`) as Person
return response;
}
当我们将用作Person
时,它会检查类型,因为我们将从API获得的任何内容显式转换为Person。这是“必要的”,因为fetchApiSync
无法知道它从外部API获取的值的类型。当然,当我们得到的不是Person类型的值而是其他类型的值时,我们会遇到问题,但对此我们无能为力。。。或者我们可以吗
此选项的另一个变体是使用TS 3中的任何
(或未知
)类型。这两个选项允许您跳过类型检查-类型any
的值可以分配给“any”类型,包括Person
。但是错误可能很难跟踪,因为在类型系统中有一个未检查的值。明智地使用它
第二种方法是使用iots
library()。它允许您指定运行时类型
并在运行时执行类型检查(因此,它引入了验证值是否与类型匹配的开销)。此外,您需要以稍微不同的方式指定这些类型(请参阅文档),以便它们可以存在于运行时。值得注意的是,io ts允许您从io ts类型定义派生纯类型脚本类型。使用io ts可以使您保持更安全的类型,并保护您的代码库不受恶意铸造或使用any
type(或unknown
TypeScript 3中的type)的影响。这样做需要一定的成本,其中一部分是不可忽略的复杂性。我认为您传递的是数字数组而不是数字。Angular中的HttpClient
允许您提示您期望的API响应的形状。如果你真的需要,你也可以在这个边界上验证它,这样你就不会在整个应用程序中传播运行时类型检查。@jack ofc我正在传递一个数字数组,问题是-如果我在typescript文件中这样做,它会给我错误,但如果我从其他来源(如后端响应)获得它第二种方法看起来很有希望,我会看看,谢谢。我已经在使用第1个,但这还不够,因为后端响应不是唯一可以传递不需要的类型的东西(另一个例子是被动表单,我编辑了我的问题来添加这个例子)。