在运行时针对TypeScript中的接口验证“任何”对象

时间:2012-10-12 22:35:11

标签: ajax validation datacontract typescript

我正在使用typescript处理应用程序的UI。 与此同时,其他人也在为我提供数据。 我们就数据合同达成了一致意见,但是这个过程很容易出错,我不断从服务器获取无效的数据对象。所以我的问题是我可以使用typescript中定义的一些接口以某种方式验证动态对象(在运行时)吗?


<子> 这个问题在2012年被提出,因此它不能与2015年提出的Check if an object implements an interface at runtime with TypeScript重复。

3 个答案:

答案 0 :(得分:8)

目前,TypeScript接口是纯粹的编译时实体,因此无法进行任何类型的运行时验证,更不用说甚至知道编译时存在哪些接口。因此,答案似乎是以下之一:

  1. 编写一些工具将TypeScript接口转换为可用于验证对象的某些运行时对象表示,或者:
  2. 将TypeScript接口复制为某些运行时对象表示
  3. 您可以使用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; }; 
}

MoverShakerMoverShaker合并到一个新的复合界面中。要验证在运行时某个给定类型是否满足接口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之类的东西。