I have an interface with a bunch of methods:
@Injectable()
export class SharedService {
serverURL: string;
expertMetadataSetSubject = new Subject<any>();
metadataEmptySubject = new Subject<void>();
singleSubject = new Subject<void>();
constructor(private http: HttpClient, private envService: EnvService) {
this.serverURL = envService.serverURL;
}
search(): Observable<String[]> {
return this.http.get<String[]>(this.serverURL 'v2/meta/profile', {});
}
onMetadataEmpty() {
this.metadataEmptySubject.next();
}
onSingleInputChange(): void {
this.singleSubject.next();
}
etc.
This service is injected in a component, that gets the function name as an @Input()
, which contains the function name, in this service, as a string.
I would like to call the appropiate method dynamically.
@Component({
selector: 'app-registration',
templateUrl: './registration.html',
styleUrls: ['./registration.css'],
})
export class RegistrationComponent implements OnInit {
@Input() name: string;
@Input() title: string;
@Input() onChange: string;
@Input() control!: FormControl;
constructor(private readonly sharedService: SharedService) {}
onClick(event: any) {
const value = event.target.innerHTML.trim();
this.control.setValue(value);
if (this.onChange) {
this.sharedService[this.onChange](value);
}
}
}
html:
<app-registration [control]="getControlByIndex('employee')" onChange="onSingleInputChange" title="namespace"></app-registration>
I got the error mentioned in the title:
error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SharedService'.
I want to avoid adding this parameter: "suppressImplicitAnyIndexErrors": true
Any idea?
Thanks
CodePudding user response:
You got this error because this.onChange
could be any string, but doesn't refer to a property necessarily in SharedService
object.
Using keyof should do the trick
this.sharedService[this.onChange as keyof SharedService](value);
or you could even do it like
@Input() onChange: keyof SharedService;
Now since keyof refers to attributes and method of the object best way would be either to create a type or an interface containing only method
// onChange: keyof ISharedService;
interface ISharedService {
onMetadataEmpty(): void;
onSingleInputChange(): void;
}
// onChange: SharedServiceMethodType;
type SharedServiceMethodType = 'onMetadataEmpty' | 'onSingleInputChange';