My custom library includes a class called FileData
:
export class FileData {
public name: string;
public data: string;
constructor(name: string, data: string) {
this.name = name;
this.data = data;
}
}
To create a deep copy of a complex object in my app, I decided to add a clone method to the existing FileData
class. Following advice from a similar question on TypeScript (source), I implemented the following code in a separate file within my shared module, as shown below:
import { FileData } from 'my-custom-library';
declare module 'my-custom-library' {
interface FileData {
clone(): FileData;
}
}
if (!FileData.prototype.clone) {
Object.defineProperty(FileData.prototype,
'clone',
{ enumerable: false,
writable: false,
configurable: false,
value: function clone(this: FileData): FileData {
return new FileData(this.name, this.data);
} });
}
In my usage of the class, I incorporated it into another class as shown here:
import { FileData } from 'my-custom-library';
export class Record extends DataEntry {
... // Other properties
public img?: FileData;
constructor(..., img?: FileData) {
... // Other initializations
this.img = img;
}
public clone(): void {
return new Record(..., img?.clone());
}
}
Although the TypeScript compiler seemed satisfied with this setup, the Angular compiler raised an error when I tried running ng build
or ng serve
:
error TS2339: Property 'clone' does not exist on type 'FileData'.
While I could simply modify my library directly to include the clone method, I prefer to maintain separation of concerns and keep the responsibility for creating deep copies within my app itself.
Is there a way to successfully add the clone method to the existing FileData
class without encountering this issue?
EDIT:
I came across a related question regarding TypeScript module augmentations in an Angular app (source). By making some modifications based on this information, I was able to achieve the desired functionality both in a StackBlitz example and in my own application. This suggests that extending classes like Observable
from rxjs
should be comparable to modifying my own FileData
class.
Despite the success with the Observable class, I encountered difficulties when attempting the same augmentation with the FileData class. The Typescript compiler did not raise any issues, but the Angular compiler failed with the message "FileData' only refers to a type, but is being used as a value here." I'm curious as to why this discrepancy exists and how it can be resolved.
The angular tool chain seems to treat the FileData class differently compared to other types like Observable. How can I ensure that Angular recognizes FileData in the same manner as Observable?