Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.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
Angular Typescript-在运行时检查键入并警告错误_Angular_Typescript - Fatal编程技术网

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

导言

我用的是角度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 '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个,但这还不够,因为后端响应不是唯一可以传递不需要的类型的东西(另一个例子是被动表单,我编辑了我的问题来添加这个例子)。