我正在使用typescript处理应用程序的UI。 与此同时,其他人也在为我提供数据。 我们就数据合同达成了一致意见,但是这个过程很容易出错,我不断从服务器获取无效的数据对象。所以我的问题是我可以使用typescript中定义的一些接口以某种方式验证动态对象(在运行时)吗?
<子> 这个问题在2012年被提出,因此它不能与2015年提出的Check if an object implements an interface at runtime with TypeScript重复。
答案 0 :(得分:8)
目前,TypeScript接口是纯粹的编译时实体,因此无法进行任何类型的运行时验证,更不用说甚至知道编译时存在哪些接口。因此,答案似乎是以下之一:
您可以使用JSON-schema作为运行时表示,因为Github上存在许多验证器。 TypeScript接口 - &gt; JSON Schema转换器是我希望有人在某些时候做出的,但据我所知,目前还不存在。
答案 1 :(得分:6)
正如Brian指出的那样,接口只在编译时表现出来,并被编译器用作所谓的命名类型。语言规范的第7节描述如下:
接口没有运行时表示 - 它们纯粹是一个编译时构造。接口对于记录和验证所需的属性形状,作为参数传递的对象以及从函数返回的对象特别有用。
在section 7.4 of the spec中进一步向下,在Typescript中有一个很好的动态类型检查描述:
TypeScript不提供动态测试对象是否实现特定接口的直接机制。相反,TypeScript代码可以使用JavaScript技术检查对象上是否存在适当的成员集......
规范中的示例定义了三个接口:
interface Mover {
move(): void;
getStatus(): {speed: number;};
}
interface Shaker {
shake(): void;
getStatus(): {frequency: number;};
}
interface MoverShaker extends Mover, Shaker {
getStatus(): { speed: number; frequency: number; };
}
MoverShaker
将Mover
和Shaker
合并到一个新的复合界面中。要验证在运行时某个给定类型是否满足接口MoverShaker
,您可以按如下方式使用Javascript代码:
var obj: any = getSomeObject();
if (obj && obj.move && obj.shake && obj.getStatus) {
var moverShaker = <MoverShaker> obj;
...
}
为了在Typescript中进行编译时检查,您需要为应用程序的两个部分之间交换的类型定义接口。目前,您必须手动编写动态检查代码(如上所述)。因此,如果您忘记同步更新它们,静态类型和动态检查代码可能会在某些时候偏离。正如Brian指出的那样,拥有一个自动生成代码的工具会很不错。
答案 2 :(得分:1)
如果您愿意,请尝试使用我的动态界面检查器,这是一个示例(full example):
interface PhysicalObject { color : Color; intact : bool; weight : number; }
class Car implements PhysicalObject {
public intact = true;
constructor(public color : Color, public weight : number) {};
}
function scratch(aCar : Car) {
typeCheck(JSVenv, arguments, schemas, ["PhysicalObject"]);
console.log("Scratching the car!");
aCar.intact = false;
}
当调用等效于scratch({ intact: 42, color: Color.RED })
的代码时,会抛出类似这样的错误:
AssertionError: Runtime typecheck failed on argument number 1:
Value: { color: 0, weight: 'four', intact: true },
Schema: ...,
Error reports (length 1):
[
{
uri: 'urn:uuid:b9b8e6fd-b14b-490d-9372-d2bd22e8a246#/weight',
schemaUri: 'urn:uuid:c76ddd92-15da-43a6-831e-6717f253efe5#/properties/weight',
attribute: 'type',
message: 'Instance is not a required type',
details: [ 'number' ]
}
]
有关说明,请参阅主页:https://github.com/ysangkok/typescript-interface-to-jsonschema
我添加了自动类型检查功能,但对于TypeScript我需要node-falafel之类的东西。