-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support type parameterized Deserialize
function
#9
Comments
How would you get the run time type information to know what to type to deserialize something into? I'm all for using generics here but since the generic constraints are a compile time feature of Typescript and not reflected in the compiled JS I'm not sure you can make this work in the same way you'd solve this problem in Java or C#. |
Maybe if you use this it would work but I'd have to try it export abstract class Deserializable {
public static deserialize<T> (json): T {
return Deserialize<T>(json, this.constructor);
}
} I'm also not sure that static methods are inherited, so it might need to be more like: export abstract class Deserializable {
public deserialize (json : any): this {
return DeserializeInto(json, this.constructor, this);
}
}
var cmd = new Command().deserialize(json); Thats using polymorphic |
@1ambda any thoughts here? I'm going to close this otherwise |
@weichx Thanks for detailed explanation and alternatives. But
I also read
but could not found any solution. It seems impossible in TypeScript and this is the limitation of TypeScript as you mentioned. My final implementation looks like export interface NoParamConstructor<T> {
new (): T
}
export abstract class Deserializable {
public static deserialize<T>(ctor: NoParamConstructor<T>, json): T {
return cerialize.Deserialize(json, ctor);
}
public static deserializeArray<T>(ctor: NoParamConstructor<T>, json): Array<T> {
return cerialize.Deserialize(json, ctor);
}
} Without NoParamConstructor, we have to pass type parameter explicitly. for example, class Car extends Deserializable {
// does not work with `deserialize`
@deserializeAs("engine") public engine: string;
@deserializeAs("wheels") public wheels: number;
}
describe("Deserializable", () => {
describe("deserialize", () => {
it("should parse Car", () => {
let json = {engine: "M5", wheels: 4};
let c1 = Car.deserialize(Car, json);
let c2 = Car.deserialize<Car>(Car, json); // without NoParamConstructor
expect(c1.engine).toEqual(json.engine);
expect(c1.wheels).toEqual(json.wheels);
});
});
}); One more question @weichx . In this case why should i use Thanks :) |
@1ambda Another thought on the above code, it seems like function DeserializeGeneric<T>(json : any, type : T) : T {
return <T>Deserialize(json, type);
} which you should be able to use like this: var car = DeserializeGeneric(json, Car); This is probably something I should add to the library, but for now I think its a cleaner solution for your use case than extending an abstract class. |
@weichx I downloaded In terms of Lastly, It would be good if you modify export function Deserialize(json : any, type? : Function|ISerializable) : any { As you mentioned, it could be // If we use NoParamConstructor technique introduced Microsoft/TypeScript#2037 it would be more type-safe.
// For example, `type: NoParamConstructor<T>` instead of just specifying `T`
export function Deserialize<T>(json : any, type: T) : T { Thanks :) |
This is now supported through |
I am writing
Dserializable
abstract class which indicate it can be deserialized and hasdeserialize
Function. It looks likeBut since
cerialize.Deserialize
requires the constructor function as the second arg, It's somewhat verbose.If we have a type parameterized
cerialize.Deserialize
function, we can make more simplifiedDeserialzable
. For example,Thanks. :)
The text was updated successfully, but these errors were encountered: