json2typescript icon indicating copy to clipboard operation
json2typescript copied to clipboard

How can one annotate or create a custom convertor for a generic type property?

Open pebkacerr opened this issue 3 years ago • 1 comments

If I try to annotate the property:

@JsonObject('MyClass')
class MyClass<T> {
     @JsonProperty("child", T) <--- does not work because: 'T' only refers to a type, but is being used as a value here) .ts(2693)
     child!: T; 
}

@JsonObject('A')
class A {
     @JsonProperty("name", String)
     name: string = '';
}

const jsonObject: any = {
      child: [
           name: null
      }
}

let jsonConvert: JsonConvert = new JsonConvert();
jsonConvert.ignorePrimitiveChecks = false;
jsonConvert.valueCheckingMode = ValueCheckingMode.DISALLOW_NULL;

const result = jsonConvert.deserializeObject(jsonObject, MyClass<A>); <--- should result in err because nulls are not allowed

If I try a custom convertor for the property:

@JsonConverter
export class GenericConvertor<T> implements JsonCustomConvert<T>  {
	serialize(data: T): any {
		let jsonConvert: JsonConvert = new JsonConvert();
		return jsonConvert.serialize(data as unknown as object);
	}

	deserialize(data: any): T {
		let jsonConvert: JsonConvert = new JsonConvert();
		jsonConvert.operationMode = OperationMode.LOGGING; // print some debug data
		jsonConvert.ignorePrimitiveChecks = false; // don't allow assigning number to string etc.
		jsonConvert.valueCheckingMode = ValueCheckingMode.DISALLOW_NULL; // never allow null

		const result = jsonConvert.deserializeObject(data, T) as unknown as T; <--- does not work because: 'T' only refers to a type, but is being used as a value here) .ts(2693)

		return result;
	}
}

@JsonObject('MyClass')
class MyClass<T> {
	@JsonProperty("child", GenericConvertor<T>)
	child!: T;
}

To address these issues I would have to pass a class reference but I cannot do that... that's the entire point of generics. How could I go around this issue. Is there any solution?

pebkacerr avatar Aug 21 '22 21:08 pebkacerr

I don't think there is a simple solution to that problem. Keep in mind that json2typescript runs in JavaScript in your compiled application and there is no such things as generics types on runtime. This means that you always need to work with types that still exist on runtime.

You can achieve a similar functionality with union types instead of generics and custom converters. Please also refer to the discriminator feature that we implemented some weeks ago that might help you achieve your goal if you do not know the type of incoming JSON.

andreas-aeschlimann avatar Aug 21 '22 21:08 andreas-aeschlimann