[英]How to conditionally set a function argument type in typescript?
I have a generic function I need to call in 2 places我有一个通用的 function 我需要在 2 个地方打电话
const functionA = (arg1, deleteFunction) => {
deleteFunction(arg1)
}
when I call it in the two different places I pass in a different deleteFunction
each time.当我在两个不同的地方调用它时,我每次都传入一个不同的
deleteFunction
。 these deleteFunctions
then update redux but they require different types so I'm getting errors这些
deleteFunctions
然后更新 redux 但它们需要不同的类型,所以我收到错误
I was wondering if for arg1
I could specify what type it should be based on properties it contains.我想知道对于
arg1
我是否可以根据它包含的属性指定它应该是什么类型。 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
显然这不起作用,但 2 个 deleteFunctions 有不同的类型(一个有
Arg1Types
另一个有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.您可以使用 function 重载,或者使用带有
function
关键字的重载语法,或者在您的问题中使用带有const
和箭头 function 的接口。
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:带有
const
和箭头 function 的 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:在这两种情况下,如果
Arg1Type
是string
并且Arg1OtherType
是number
(例如),则这些调用有效:
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.;在这两种情况下,IDE 等只会显示重载签名(前两个); 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.
Arg1Type 和 Arg1OtherType 都是对象,但在这些对象内部,每个属性的类型不同。 ... 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. TypeScript 将根据 arguments 的类型推断要使用的正确过载。 In my examples, the types are
string
and number
.在我的示例中,类型是
string
和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. 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只允许接受数字的 function。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.