使用TypeScript和Angular2验证传入数据的类型

时间:2017-05-04 08:18:16

标签: angular typescript

我想知道通过AJAX或通过Angular2 +应用程序中的@input装饰器验证从服务器收到的数据的推荐方法。在我目前使用的应用程序中,我使用接口,但它们不验证传入数据,即当缺少某些属性时,不会发出关于无效类型的运行时错误:

// types.ts
export interface IAuthItem {
name: string;
type: number;
description: string;
rule_name: string | any;
data?: any;
created_at: number;
updated_at: number;
selected?: boolean;
}

export interface IAuthItemFormModel {
AuthItem: IAuthItem;
oldAuthItem: IAuthItem;
permissions: IAuthItem[];
assignments: IAuthItem[];
}

// component.ts

//other imports
import { IAuthItemFormModel,  IAuthItem  } from './types.ts';

....

@Input() model: IAuthItemFormModel;

  ngOnInit() {
  this.getData();
}

getData() {
  this.http.post('/api/admin/auth-item/form-data', 
    this.model).subscribe((data: IAuthItemFormModel) => {
  this.model = Object.assign(this.model, data);
  console.log(this.model);
  });
}

2 个答案:

答案 0 :(得分:0)

JS上不存在接口,您应该认为TS是JS的超集,但它会被转换为JS,这是浏览器所理解的。

该界面仅供您提供一些Intellisense和编译时错误以供开发。

话虽如此,你必须通过JS验证该对象的唯一方法是查看params。你有几种方法,其中一种是 getOwnPropertyNames

  

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/getOwnPropertyNames

答案 1 :(得分:0)

  

免责声明:这纯粹是一种可能的方法的例子,这并不意味着它需要有效或者其他什么,这只是我最近使用的方法并且允许弹性,这就是我所期待的对

现在,重点。

由于接口在运行时不存在,如果要解析并有效地添加任何类型的“测试”以获取所需数据并最终转换所获取的数据,则应该使用类。

这是一个小例子,模拟这个回应:

const json_response = {
    status: "done",
    refere: {
        "id": 13,
        "name": "John"
    }
};

在我们的例子中,我将要应用的逻辑是一个负责处理整个响应的响应处理程序,以及一个处理引用引用的Referee类。

从裁判开始:

interface IReferee {
    id: number,
    name:   string
}

class Referee implements IReferee {
    public id: number;
    public name: string;

    private rawData: any;

    constructor(data?: any) {
        if (data !== null) {
            // Do some check here to check whether data is effectively coherent.
            this.id = +data.id;
            this.name = data.name;
        }
    }

    // This is the advantage of using a class.
    // Adding optional methods that may be useful here and there.
    get ID(): number {
        return this.id;
    }

    get LowerCaseName(): string {
        return this.name.toLowerCase();
    }

    get Name(): string {
        return this.name;
    }

    get UpperCaseName(): string {
        return this.name.toUpperCase();
    }
}

接口不是强制性的,确保在类本身中正确实现所有内容非常有用。这里的优点是,如果您愿意,可以实现自己的方法(如上所示)。

响应处理程序:

interface IMyJsonResponseHandler {
    status: string,
    refere: Referee 
}

class MyJsonResponseHandler implements IMyJsonResponseHandler {
    private rawData: any;

    public status: string;
    public refere: Referee;

    constructor(data?: any) {
        if (data !== null) {
            this.status = data.status;
            this.refere = new Referee(data.refere);
        }
    }

    get Refere(): Referee {
        return this.refere;
    }
}

并且应用了相同的标准:基本上,这里提供的参数是json响应。每个单独的处理都在构造函数中完成,如果你想添加任何严格的检查,那么在那里进行并最终抛出错误或者你需要的任何东西。通过这种方式,您可以访问json响应的所有内容,并且可以通过接口和类一起享受intellisense。当然你可以简单地接受JSON响应是无类型的,但是如果你需要做一些严格的检查并且需要这些数据用于其他计算,或者只是想更容易理解属性是什么,那么你必须使用类并做检查那里,因为打字稿中的接口只不过是这种情况下开发人员的一种安慰。

使用示例:

const json_response = {
    status: "done",
    refere: {
        "id": 13,
        "name": "John"
    }
};
let res = new MyJsonResponseHandler(json_response);

console.log(res.Refere.LowerCaseName);

Playground with this example 记录:john

此标准的优点:智能感知。

或者,您可以轻松实现一个接口,但是如果您需要复杂的数据详细说明(或者,如果您需要将内部属性实例化为类实例),则必须使用其他条件。

您应该检查其他来源:

How to parse JSON string in Typescript

How do I cast a JSON object to a typescript class