If the object is based on an Interface some of the members might not be callable (they are not functions). In this case you must specify exactly which member names are allowed as an index.
Also this only works if the parameter type of the member functions is the same but you can overcome this limitation with type any and check for correct parameters inside your function.
interface OnlyMethodsIf {
sayHi: (val: string) => void;
sayBye(val: string): string;
}
const onlyMethods : OnlyMethodsIf = {
sayHi: (val: string) : void => { /* do some stuff */ },
sayBye(val: string) : string { return 'someString'}
}
//if all members are callable we can just use "keyof OnlyMethodsIf" as member type
const callToOnlyMethods = (member: keyof OnlyMethodsIf, val: string) => {
onlyMethods[member](val);
}
interface MixedMembersIf {
sayHi: (val: string) => void;
sayBye(val: string): void;
word: string; //not a method/function
}
const mixedMembers : MixedMembersIf = {
sayHi: (val: string) : void => { /* do some stuff */ },
sayBye(val: string) : string { return 'someString'},
word: "Ola",
}
//this will not work, "word" is not a callable member of MixedMembersIf
const callToMixedIncorrectly = (member: keyof MixedMembersIf, val: string) => {
mixedMembers[member](val);
}
// defining which members are callable - 'member: "sayHi" | "sayBye"'
const callToMixedCorrectly = (member: "sayHi" | "sayBye", val: string) => {
mixedMembers[member](val);
}
//real life use case
const callMathFunction = (
type: 'round' | 'ceil' | 'floor' | 'trunc',
num: number,
) => {
return Math[type](num);
};
Here is an example of how to overcome same type for function members limitation:
interface OnlyMethodsNoLimits {
sayHi: (param: any) => number;
sayBye(param: any): string;
sayNothing: () => void;
}
const onlyMethodsNoLimits : OnlyMethodsNoLimits = {
sayHi: (param: any) : number => {
/* check param type here */
console.log("called 'sayHi', param:", param);
return param
},
sayBye(param: any) : string {
/* check param type here */
console.log("called 'sayBye', param:", param);
return param
},
sayNothing: () : void => {
console.log("called 'sayNothing'");
},
}
const callToOnlyMethodsNoLimits = (member: keyof OnlyMethodsNoLimits, param?: any) => {
return onlyMethodsNoLimits[member](param);
}
console.log("sayHi with number param returns:",callToOnlyMethodsNoLimits("sayHi", 53));
console.log("sayHi with string param returns:",callToOnlyMethodsNoLimits("sayHi", "a string"));
console.log("sayHi withouth param returns:",callToOnlyMethodsNoLimits("sayHi"));
console.log("sayBye with number param returns:",callToOnlyMethodsNoLimits("sayBye", 53));
console.log("sayBye with string param returns:",callToOnlyMethodsNoLimits("sayBye", "a string"));
console.log("sayBye withouth param returns:",callToOnlyMethodsNoLimits("sayBye"));
console.log("sayNothing with number param returns:",callToOnlyMethodsNoLimits("sayNothing", "a string"));
console.log("sayNothing with string param returns:",callToOnlyMethodsNoLimits("sayNothing", 53));
console.log("sayNothing withouth param returns:",callToOnlyMethodsNoLimits("sayNothing"));
this.someArray[theIndex]