In my typescript file, I have a list of operations. Some of these are strings that needs to be executed and others are callable functions:
const operations: {title: string, method: Function | string}[] = [
{
title: `some powershell script`,
method: `some powershell script`
},
{
title: `function`,
method: () => console.log("function"),
}
];
if (typeof operations[i].method === `function`) {
typeof operations[i].method() // ERROR: This expression is not callable. No constituent of type 'string | Function' is callable.
}
if (typeof operations[i].method === `string`) {
exec(operations[i].method) // ERROR: Argument of type 'string | Function' is not assignable to parameter of type 'string'. Type 'Function' is not assignable to type 'string'.
}
Is there a way to resolve this typescript error without using any?
Thanks!
CodePudding user response:
How about forcing the type using as ?
The complete code would be:
const operations: {title: string, method: Function | string}[] = [
{
title: `some powershell script`,
method: `some powershell script`
},
{
title: `function`,
method: () => console.log("function"),
}
];
if (typeof operations[i].method === `function`) {
const op = operations[i].method as Function;
typeof op();
}
if (typeof operations[i].method === `string`) {
const op = operations[i].method as string;
exec(op);
}
CodePudding user response:
Your code does indeed work in newer versions of TypeScript, as you verify it here, so upgrading TypeScript would work.
However, the type Function
is very generic, this is because you're using any
implicitly for the return and ...args: any[]
for the arguments, so if you want to avoid using any
at all costs, type the object as such:
{title: string, method: (() => unknown) | string}
If you know the exact type that the method will return, you can use other types aside from unknown
, if you don't, unknown
will say it has a consistent type, which is the same as "any
excluding never
".
CodePudding user response:
Create an additional variable to check against, for example with object destructuring within a loop:
for (const operation of operations) {
const { method } = operation;
if (typeof method === `function`) {
method(); // Function
}
if (method === `string`) {
exec(method); // string
}
// Or even simpler
// typeof method === `function` ? method() : exec(method);
}