繁体   English   中英

如何有条件地在 typescript 中设置 function 参数类型?

[英]How to conditionally set a function argument type in typescript?

我有一个通用的 function 我需要在 2 个地方打电话

const functionA = (arg1, deleteFunction) => {
 deleteFunction(arg1)
}

当我在两个不同的地方调用它时,我每次都传入一个不同的deleteFunction 这些deleteFunctions然后更新 redux 但它们需要不同的类型,所以我收到错误

我想知道对于arg1我是否可以根据它包含的属性指定它应该是什么类型。 像这样的东西

const functionA = (arg1: arg1.hasSomeProperty ? Arg1Types : Arg1OtherType, deleteFunction) => {
 deleteFunction(arg1)
}

显然这不起作用,但 2 个 deleteFunctions 有不同的类型(一个有Arg1Types另一个有Arg1OtherTypes

可能会以完全错误的方式进行。 有任何想法吗?

您可以使用 function 重载,或者使用带有function关键字的重载语法,或者在您的问题中使用带有const和箭头 function 的接口。

重载语法:

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);
}

游乐场链接

带有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);
};

游乐场链接

在这两种情况下,如果Arg1Typestring并且Arg1OtherTypenumber (例如),则这些调用有效:

functionA("foo", (id) => {
    // ...do the deletion...
});

functionA(42, (id) => {
    // ...do the deletion...
});

...而这些不会:

// 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);
});

在这两种情况下,IDE 等只会显示重载签名(前两个); 实现签名不是。

在此处输入图像描述

在此处输入图像描述

在评论中你说:

...调用此函数如何知道要使用哪些类型? Arg1Type 和 Arg1OtherType 都是对象,但在这些对象内部,每个属性的类型不同。 ...我想进一步了解条件部分

TypeScript 将根据 arguments 的类型推断要使用的正确过载。 在我的示例中,类型是stringnumber 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。

对于具有不同形状的对象也可以这样:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM