So I have this interface for a "full document" object:
export interface FullDocument {
id: string,
title: string,
content: string,
metadata: {
author: string,
createdAt: Date,
updatedAt: Date
}
hash: Int32Array
}
In the code I want to create a new FullDocument via a var (lets assume I do that without class, just by declaring a var and that all global vars are available):
var myNewDocument: FullDocument = {
id: getUUID(),
title: title,
content: textArea,
metadata: {
author: author,
createdAt: new Date(),
updatedAt: new Date(),
}
hash: null
}
Now I do want to hash the document after it is instantiated / created, so initially I can not add such a hash since its not available (at least I think so), so I do that afterwards:
myNewDocument.hash = hasherMethod(myNewDocument);
So question: if I have a field that is typed (as Int32Array here) but I can't add legit value in there during instantiation is my option just to do "hash?" - the question mark that marks the property as optional? Or is there a classic way how this is normally done?
Another approach I thought could be that I differentiate types and do:
- unhashedFullDocument type
- hashed fullDocument type
So how do typescripters do it?
So I have this interface for a "full document" object:
export interface FullDocument {
id: string,
title: string,
content: string,
metadata: {
author: string,
createdAt: Date,
updatedAt: Date
}
hash: Int32Array
}
In the code I want to create a new FullDocument via a var (lets assume I do that without class, just by declaring a var and that all global vars are available):
var myNewDocument: FullDocument = {
id: getUUID(),
title: title,
content: textArea,
metadata: {
author: author,
createdAt: new Date(),
updatedAt: new Date(),
}
hash: null
}
Now I do want to hash the document after it is instantiated / created, so initially I can not add such a hash since its not available (at least I think so), so I do that afterwards:
myNewDocument.hash = hasherMethod(myNewDocument);
So question: if I have a field that is typed (as Int32Array here) but I can't add legit value in there during instantiation is my option just to do "hash?" - the question mark that marks the property as optional? Or is there a classic way how this is normally done?
Another approach I thought could be that I differentiate types and do:
- unhashedFullDocument type
- hashed fullDocument type
So how do typescripters do it?
Share Improve this question asked Jul 20, 2018 at 16:34 Sergey RudenkoSergey Rudenko 9,2653 gold badges32 silver badges52 bronze badges 1- 1 Depends on the usecase – Jonas Wilms Commented Jul 20, 2018 at 16:42
4 Answers
Reset to default 4This depends on the details, but a situation where there is a field which might not be there at one time and then might be there at another time can often be a sign of poor design (even though TypeScript aids and abets you in this with the ?
notation).
Ask yourself: is the hash really part of the document, or is it associated with the document? If the latter is a more accurate description, then you might consider alternatives such as a weakmap, keyed by document, holding the hash--and such an approach might have other advantages as well.
If you don't want to spend too much time thinking about the inner nature of documents and drawing fine distinctions between notions of "belongs to" and "associated with", then just go with an optional field.
The alternative, of course, again depending on your use case, is to calculate the hash on as as-needed basis, if, for example, it depends on the content of the document and that content might have changed. Speaking of which, what is this hash supposed to mean, and what is it going to be used for?
You use typescript to gain typesafety, so which approach you choose depends on the exact usecase:
interface FullDocument {
//...
hash?: Int32Array;
}
That means that FullDocument
might have a hash, or it might not. Therefore whenever you work with FullDocument types and want to access the hash
you have to check if it is existing already. Now in cases were you definetly need the hash, you can just fix the type:
const withHash: (FullDocument & { hash: Int32Array })[] = [];
And then you have to check if the hash is existing on every insert.
I agree with torazaburo that the situation you've described makes it sound like the hash maybe shouldn't be part of your object model at all.
I'm envisioning a situation where you've got a ponent, service, or data type that requires all of its "things" to have a hash property on them, and you're thinking of adding this property to your model in order to be able to pass your objects to it.
In a case like this, I'd consider using Composition: you can create a new, generic type that has two properties: an object and its hash. Objects of this type can be used to provide a hash, without modifying other types, thereby following the Open/Closed Principle.
Just set it to null or undefined at instantiation. Unless you have the strictNullChecks flag set, all types are assignable to null and undefined.