Reputation: 93
I have a bunch of custom pipes like this:
@Pipe({ name: 'appPadThree', pure: true, standalone: true })
@Injectable()
export class PadThreePipe implements PipeTransform {
transform(value: number): string {
// Code
}
}
I'm trying to write a generic function to use .transform()
but .transform()
doesn't exist on type Pipe.
Attempt 1:
pipeData<T>(value: string, pipeName: T): string {
const pipeWorker = inject(pipeName);
return pipeWorker.transform(value);
}
Attempt 2:
pipeData<T extends PipeTransform>(value: string, pipeName: T): string {
return pipeRef.transform(value);
}
Error: Argument of type 'Pipe' is not assignable to parameter of type 'PipeTransform'. Property 'transform' is missing in type 'Pipe' but required in type 'PipeTransform'.
This code worked prior to the Angular 18 / standalone upgrade. It didn't use generics and was ugly.
pipeData(value: any, pipeName: any): any {
const pipeWorker = this.injector.get(pipeName);
return pipeWorker.transform(value);
}
How can I write a generic function that takes a Pipe as the type, knowing that it implements PipeTransform?
EDIT The caller gets a little complicated. I have an interface that looks like this:
export interface ITableViewer {
...
displayPipe?: Pipe;
}
My object looks like this:
{ ... displayPipe: PadThreePipe },
And the caller:
this.pipeData(displayString, pipeName);
Upvotes: 0
Views: 105
Reputation: 51485
Solution for Attempt 1
As you provide the PadThreePipe
as type to the displayPipe
field:
let pipeRef = { displayPipe: PadThreePipe };
let pipeName = pipeRef.displayPipe;
this.pipeData(displayString, pipeName)
You should refer to the class type by the constructor function. Reference: Generic Type Inference with Class Argument
pipeData<T>(value: string, pipeName: new () => T): string {
const pipeWorker = inject(pipeName);
return pipeWorker.transform(parseInt(value));
}
Solution for Attempt 2
Provide the PadThreePipe
instance to the displayPipe
field.
let pipeRef = { displayPipe: new PadThreePipe() };
let pipeName = pipeRef.displayPipe;
this.pipeData(displayString, pipeName);
Change the second argument name to pipeRef
.
pipeData<T extends PipeTransform>(value: string, pipeRef: T): string {
return pipeRef.transform(value);
}
Upvotes: 0