Home > database >  error TS7053: Element implicitly has an 'any' type because expression of type 'string
error TS7053: Element implicitly has an 'any' type because expression of type 'string

Time:10-28

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';
  • Related