我对Typescript很新,并且在我的代码工作方面遇到了一些问题。我有以下接口/类结构
interface IInterface {
id : number;
method() : string;
}
class IClass implements IInterface {
id : number;
method() : string { return "foo";}
}
现在我希望通过以下调用从Web服务获取一些数据
$.get("/some/url", (data : Array<IInterface>) => {
for (var i = 0; i < data.length; i++) {
console.log(data[i].id);
console.log(data[i].method());
}
});
虽然这可以很好地编写打字稿并且所有属性都设置得很好,但我得到一个运行时TypeError data[i].method is not a function
所以现在我的问题是:如何正确地转换/赋值(?),以便在生成的JavaScript中也可以使用这些方法?
UPDATE 根据要求:转发我从网络服务获得的数据。
data = [{id : 1}, {id : 2}, ...]
当然,这是一个简化的例子,真正的类/接口有一些更多的属性(它们都被正确分配),但也只有一个方法(到目前为止,当我让它工作时,还会有更多的方法)。
答案 0 :(得分:1)
这是将JSON对象转换为类实例的常见问题。这里讨论了一些提案:JSON to TypeScript class instance?
以下是我提出的进行反序列化的解决方案:
export class Helper
{
public static DESCRIPTOR_SIGN = '$';
private static m_entityModules = [];
private static ReviveDateTime(key: any, value: any): any
{
if (typeof value === 'string')
{
let a = /\/Date\((\d*)\)\//.exec(value);
if (a)
{
return new Date(+a[1]);
}
}
return value;
}
private static RessurectValue(json: any, environments: any[]): any
{
if(json == null)
{
return null;
}
else if(Helper.IsString(json))
{
return json;
}
else if(json instanceof Date)
{
return json;
}
else if(typeof json === 'object')
{
return Helper.RessurectInternal(json, environments);
}
else
{
return json;
}
}
private static RessurectInternal(json: any, environments: any[]): any
{
var instance;
if(!json[Helper.DESCRIPTOR_SIGN])
{
instance = {};
}
else
{
instance = Helper.CreateObject(json[Helper.DESCRIPTOR_SIGN]);
if(Helper.IsUndefined(instance))
{
throw new Error('Unknown type to deserialize:' + json[Helper.DESCRIPTOR_SIGN]);
}
}
for(var prop in json)
{
if(!json.hasOwnProperty(prop) || prop === Helper.DESCRIPTOR_SIGN)
{
continue;
}
let val = json[prop];
instance[prop] = Helper.Ressurect(val, environments);
}
return instance;
}
private static CreateObject(className: string, environments?: any[]): any
{
let instance: any;
for(let e of environments)
{
var construct = e[className];
if(!Helper.IsUndefined(construct))
{
instance = new construct();
break;
}
}
return instance;
}
private static IsNumber(val: any): boolean
{
return typeof val == 'number' || val instanceof Number;
}
private static IsUndefined(val: any): boolean
{
return typeof(val) === 'undefined';
}
private static IsString(val: any): boolean
{
return typeof val == 'string' || val instanceof String;
}
/**
* Deserialize json object object into TypeScript one.
* @param json json object that must have its class name in '$' field
* @param environments list of modules containing all types that can be encountered during deserialization
* @return deserialized typescript object of specified type
*/
public static Ressurect(val: any, environments: any[]): any
{
if(val instanceof Array)
{
if(val.length == 0)
{
return val;
}
else
{
let firstElement = val[0];
if(typeof firstElement !== 'object')
{
return val;
}
else
{
let arr = [];
for (var i = 0; i < val.length; i++)
{
var element = val[i];
arr.push(Helper.RessurectValue(element, environments));
}
return arr;
}
}
}
else
{
return Helper.RessurectValue(val, environments);
}
}
}
以上的一些注意事项。它的工作原理是:
使用样本。让我们假设你已经在一个名为&#39; Types&#39;的外部模式中定义了所有可序列化的类。然后反序列化你写的JSON对象:
import * as types from './Types'
//Some code to get jsonObj that has jsonObj.$ set to "RealObject" - a type from "Types" module
let realObj = <types.RealObject>Helper.Resurrect(jsonObj, [types]);
希望这有帮助。