I am working on a WebSocket message system, and need some way to identify the type of a message when it is received. I have an abstract Message
class, and then have a class for each type of message, which all extend Message
. I have declared public static readonly classId
as a member of Message
, and then set this value for each extension of Message
. I would like TypeScript to give an error if you try to extend Message
but don't define classId
. How could this be done?
Asked
Active
Viewed 105 times
0

John Leuenhagen
- 576
- 7
- 23
-
1There is currently [no support](https://github.com/microsoft/TypeScript/issues/14600) for `abstract static` properties in TypeScript. – jcalz May 10 '19 at 14:23
-
This thread may be of use: https://stackoverflow.com/questions/43723313/typescript-abstract-class-static-method-not-enforced – John Leuenhagen May 10 '19 at 14:23
-
You have to make classId not static so it can be abstract protected so derived classes are forced to have it as a field – makeitmorehuman May 10 '19 at 14:40
1 Answers
0
You can not force abstraction down the chain with static methods. Just use public readonly abstract
if possible:
abstract class Message {
public readonly abstract classId: string;
}
interface IMessageParams {
classId: string;
}
class MessageTypeA extends Message {
constructor(public readonly classId = "MessageTypeA") {
super();
}
}
const msgA1 = new MessageTypeA();
// leaves software for exachage
const json = JSON.stringify(msgA1);
// comes back to software domain
const messageParams: IMessageParams = JSON.parse(json);
// get back your message type A:
const msgA2 = new MessageTypeA(messageParams.classId);
alert(msgA2 instanceof MessageTypeA); //true

makeitmorehuman
- 11,287
- 3
- 52
- 76
-
I want each Type of Message to have a unique `classId`. e.g. `MessageTypeA.classId` should be able to be accessed, and should be the same for all instances of `MessageTypeA`. – John Leuenhagen May 10 '19 at 16:44
-
I could answer better if you explain how / why you need this id, as if there is 1 to 1 relationship between class type and its id, often you can just use the class for representing the type. either using a mapping or by instanceOf MessageTypeA etc. – makeitmorehuman May 10 '19 at 23:21
-
Unfortunately, this information is lost when using `JSON.stringify`. I need this id for adding back the prototype information after using `JSON.parse` – John Leuenhagen May 12 '19 at 02:17
-
Not sure how you stringufy but it should never remove public fields. they will convert to and from json just fine. how do you do it? – makeitmorehuman May 12 '19 at 16:20
-
`instanceof` does not work after using `JSON.stringify`, as the prototype is not stored in JSON. That's the issue – John Leuenhagen May 12 '19 at 19:33
-
JSON is an exchange format not part of the language. All information to do with types, classes, etc. are lost once you serialise your data to be sent out. You need to use the JSON again to recreate instances through the constructor once they are back in your software domain. – makeitmorehuman May 12 '19 at 19:52
-
-
I am aware of this, which is why I am adding in classId so that I know which prototype to reapply once I parse the serialized data. – John Leuenhagen May 12 '19 at 20:06