I have a generic function I need to call in 2 places
const functionA = (arg1, deleteFunction) => {
deleteFunction(arg1)
}
when I call it in the two different places I pass in a different deleteFunction
each time. these deleteFunctions
then update redux but they require different types so I'm getting errors
I was wondering if for arg1
I could specify what type it should be based on properties it contains. something like this
const functionA = (arg1: arg1.hasSomeProperty ? Arg1Types : Arg1OtherType, deleteFunction) => {
deleteFunction(arg1)
}
obviously this doesn't work but the 2 deleteFunctions have different types (one has Arg1Types
the other has Arg1OtherTypes
might be going about it in completely the wrong way. any ideas?
You can use a function overload, either using overload syntax with the function
keyword, or using an interface with const
an an arrow function as in your question.
Overload syntax:
function functionA(arg: Arg1Type, deleteFunction: (arg: Arg1Type) => void): void;
function functionA(arg: Arg1OtherType, deleteFunction: (arg: Arg1OtherType) => void): void;
function functionA(arg: any, deleteFunction: (arg: any) => void): void {
deleteFunction(arg);
}
A function interface with const
an an arrow function:
interface FunctionA {
(arg: Arg1Type, deleteFunction: (arg: Arg1Type) => void): void;
(arg: Arg1OtherType, deleteFunction: (arg: Arg1OtherType) => void): void;
}
const functionA: FunctionA = (arg: any, deleteFunction: (arg: any) => void): void => {
deleteFunction(arg);
};
In both cases, if Arg1Type
is string
and Arg1OtherType
is number
(for example), these calls work:
functionA("foo", (id) => {
// ...do the deletion...
});
functionA(42, (id) => {
// ...do the deletion...
});
...and these don't:
// Error: No overload matches this call.
// (because the types don't match)
functionA("foo", (id: number) => {
// ...do the deletion...
console.log(id);
});
// Error: No overload matches this call.
// (because no overload takes an object)
functionA({}, (id) => {
// ...do the deletion...
console.log(id);
});
And in both cases, only the overload signatures (the first two) will be shown by IDEs, etc.; the implementation signature isn't.
In a comment you've said:
...how the invoking of this functions knows which types to use? Arg1Type and Arg1OtherType are both objects but inside these objects, the types are differents for each property. ... I'd like to understand the conditional part a bit more
TypeScript will infer the correct overload to use based on the types of the arguments. In my examples, the types are string
and number
. When I started with functionA("foo",
TypeScript could tell that I was using the string
overload and will only allow a function that accepts a string. When I started with functionA(42,
TypeScript could tell I was using the number
overload and will only allow a function that accepts a number.
That's fine with objects with different shapes as well:
interface Arg1Type {
prop: string;
}
interface Arg1OtherType {
prop: number;
}
functionA({"prop": "foo"}, (obj) => {
// ...do the deletion...
console.log(obj);
});
functionA({"prop": 42}, (obj) => {
// ...do the deletion...
console.log(obj);
});
type A = string
type B = number
type Arg1 = A | B
const functionA = (arg1: Arg1, deleteFunc: (arg1: Arg1) => void): void {
deleteFunc(arg1);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.