interface ExampleType { [key: string]: string | (() => string); } const testObj: ExampleType = { firstName: "Peter", lastName: "Parker", gender: "male", getFullName: () => "I am Peter Parker", }; const { firstName, lastName, getFullName } = testObj; console.log(getFullName()); // this does not works if (typeof getFullName === "function") { console.log(getFullName()) // this works } I am getting following error: **This expression is not callable. Not all constituents of type 'string | (() => string)' are callable. Type 'string' has no call signatures. **
1 Answer
By saying testObj: ExampleType, you are saying that testObj will be an object in which the properties are either string or () => string. That's a broad, weak promise. However, you know exactly which properties will be of which kind.
Solution one
Tell the compiler everything you know. Include concrete property names in ExampleType.
interface ExampleType { firstName: string; lastName: string; gender: string; getFullName: () => string; } const testObj: ExampleType = { firstName: "Peter", lastName: "Parker", gender: "male", getFullName: () => "I am Peter Parker", }; const { firstName, lastName, getFullName } = testObj; console.log(getFullName()); // this works Solution two
If you want to use ExampleType as a blueprint, but want the specific properties inferred for you, use a helper function like specific defined below.
interface ExampleType { [key: string]: string | (() => string); } const specific = <T>() => <U extends T>(argument: U) => argument; const testObj = specific<ExampleType>()({ firstName: "Peter", lastName: "Parker", gender: "male", getFullName: () => "I am Peter Parker", }); const { firstName, lastName, getFullName } = testObj; console.log(getFullName()); // this works 1