TypeScript没有正确推断Union的返回类型



我不知道这种语法是否正确,或者有更好的方法。我试着让TypeScript正确地获取返回另一个函数的函数的返回类型。

type A = () => void;
type B = (id: number) => void;
type C = (id: number, title: string) => void;
type D = A | B | C;
interface Funcs {
[key: string]: (fn) => D
}

Funcs是一个包含一系列函数的对象,它返回a、B或c类型的函数。例如:

{
addPerson: (fn) => () => return fn(add());
deletePerson: (fn) => (id) => return fn(delete(id));
updatePerson: (fn) => (id, title) => return fn(update(id, title));
}

当我尝试调用其中一个函数时。返回类型的签名混乱

如果你使用Funcs, TypeScript不能推断出这些返回类型。但是你可能不需要Funcs

问题中有几个语法错误等,但如果我做出合理的假设,我认为你的意思是这样的:

type A = () => void;
type B = (id: number) => void;
type C = (id: number, title: string) => void;
type D = A | B | C;
type FnParamType = unknown;
type Fn = (param: FnParamType) => void;
declare const addSomething: () => FnParamType;
declare const deleteSomething: (id: number) => FnParamType;
declare const updateSomething: (id: number, title: string) => FnParamType;
interface Funcs {
[key: string]: (fn: Fn) => D;
}
const fns: Funcs = {
addPerson: (fn) => () => { fn(addSomething()); },
deletePerson: (fn) => (id: number) => { fn(deleteSomething(id)); },
updatePerson: (fn) => (id: number, title: string) => { fn(updateSomething(id, title)); },
};

操场上联系

对于TypeScript来说,没有什么可以用来区分这些函数返回什么,所有的函数都接受fn(你没有键入,但我猜它们都是相同的类型)。TypeScript根本不能推断其中一个将返回() => void而另一个返回(id: number) => void,等等。

但是如果你不使用Funcs, TypeScript会正确地输入addPerson等:

const fns = {
addPerson: (fn: Fn) => () => { fn(addSomething()); },
deletePerson: (fn: Fn) => (id: number) => { fn(deleteSomething(id)); },
updatePerson: (fn: Fn) => (id: number, title: string) => { fn(updateSomething(id, title)); },
};
// These all work fine and have appropriate parameter hints:
fns.addPerson((param: FnParamType) => {})();
fns.deletePerson((param: FnParamType) => {})(42);
fns.updatePerson((param: FnParamType) => {})(42, "answer");

操场上联系

类型和对象是不同的类型。很难理解你到底想要两者中的哪一个,所以可能的解决方案很少。

  1. 假设类型正确,编辑对象
type A = () => void;
type B = (id: number) => void;
type C = (id: number, title: string) => void;
type D = A | B | C;
interface Funcs {
[key: string]: () => D
}
const Q: Funcs = {
addPerson: () => () => {},
deletePerson: () => (id) => {},
updatePerson: () => (id, title) => {},
}
Q.updatePerson()(1, 'title') // example call
  1. 假设对象正确,编辑类型
type A = () => () => void;
type B = (id: number) => () => void;
type C = (id: number, title: string) => () => void;
type D = A | B | C;
interface Funcs {
[key: string]: D
}
const Q: Funcs = {
addPerson: () => () => {},
deletePerson: (id) => () => {},
updatePerson: (id, title) => () => {},
}
Q.updatePerson(1, 'title')() // example call
  1. 最简单的一个,以防万一你实际上不想要函数中的函数,因为它似乎不需要它。
type A = () => void;
type B = (id: number) => void;
type C = (id: number, title: string) => void;
type D = A | B | C;
interface Funcs {
[key: string]: D
}
const Q: Funcs = {
addPerson: () => {},
deletePerson: (id) => {},
updatePerson: (id, title) => {},
}
Q.updatePerson(1, 'title') // example call

注意,我使用了空体函数({})而不是您的函数代码。很难说为什么你在这里做return delete(id);而不是delete(id),但它似乎是一个简化的例子。

首先,我必须正确地定义它。Funcs是包含dictionary定义的接口。该字典对象的值类型定义如下;

() => D

,其中类型D是;

的并集
type A = () => void;
type B = (id: number) => void;
type C = (id: number, title: string) => void;
type D = A | B | C;

这意味着,它将接受具有不同参数体的函数,并且不返回任何值。

在你的例子中;

{
addPerson: () => () => return add();
deletePerson: (id) => () => return delete(id);
updatePerson: (id, title) => () => return update(id, title
}

给定值的返回类型与您的联合类型匹配(最有可能,但我们不知道添加,删除或更新函数的实际实现,我假设它们不返回),但是函数参数不为任何示例。为了达到你想要达到的效果,你必须指定一个额外的类型,如;

type X = () => D;
type Y = (id: number) => D;
type Z = (id: number, title: string) => D;
type T = X | Y | Z;

interface Funcs {
[key: string]: T
}

现在,您有一个名为T的字典类型,它接受具有3个不同参数体的函数,并且每个函数都返回另一个类型为D的函数。

最新更新