Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用不同的回调重载参数干净地编写TypeScript函数_Typescript_Typescript2.4 - Fatal编程技术网

如何使用不同的回调重载参数干净地编写TypeScript函数

如何使用不同的回调重载参数干净地编写TypeScript函数,typescript,typescript2.4,Typescript,Typescript2.4,这是 鉴于此代码: 类动物{ a:弦; } 狗类动物{ b:弦; } 类Foo{} 功能测试(动物:A,func:(p:A)=>T):T; 功能测试(动物:A,func:(p:A)=>Foo):Foo; 功能测试(动物:A,功能:(p:A)=>T | Foo:T | Foo{ 返回函数(动物); } 是否有一种更干净的方式来编写不需要a类型参数的重载?或者是一个写这些东西的清洁工?基本上,函数使用给定的animal有条件地调用给定的func。如果给狗,则返回类型T。如果给予其他动物,则返回类型

这是

鉴于此代码:

类动物{
a:弦;
}
狗类动物{
b:弦;
}
类Foo{}
功能测试(动物:A,func:(p:A)=>T):T;
功能测试(动物:A,func:(p:A)=>Foo):Foo;
功能测试(动物:A,功能:(p:A)=>T | Foo:T | Foo{
返回函数(动物);
}
是否有一种更干净的方式来编写不需要a类型参数的重载?或者是一个写这些东西的清洁工?基本上,函数使用给定的
animal
有条件地调用给定的
func
。如果给狗,则返回类型
T
。如果给予其他动物,则返回类型
Foo

更新1 我无法让@jcalz版本正常工作,但我花了一段时间才意识到它与承诺有关,但我不确定如何解决这个问题。以下是我的“丑陋但有效”的方法论和@jalz的“很好,但已经破产”的方法论:

类动物{
a:弦;
}
狗类动物{
b:弦;
}
类Foo{}
功能测试(动物:A,func:(p:A)=>Promise):Promise;
功能测试(动物:A,func:(p:A)=>Promise):Promise;
功能测试(动物:A,func:(p:A)=>Promise | Promise):Promise{
返回函数(动物);
}
const-foo:Promise=test(new-Animal(),(a)=>{return-Promise.resolve(new-foo());});
const-other:Promise=test(newdog(),(d)=>{return-Promise.resolve(d.b);});
类型AnimalFunc={
(狗:狗):承诺;
(动物:动物):承诺;
}
功能测试2(dog:dog,func:AnimalFunc):承诺;
功能测试2(动物:动物,功能:动物基金):承诺;
功能测试2(动物:动物,功能:动物基金):承诺{
返回函数(动物);
}
const foo2:Promise=test2(新动物(),
(a) =>{
return Promise.resolve(new Foo());
}); // 错误:类型为“(a:any)=>Promise”的TS2345参数不能分配给类型为“AnimalFunc”的参数。
//类型“Promise”不可分配给类型“Promise”。
//类型“Foo”不可分配给类型“string”。类型脚本虚拟项目C:\\u Dev\CRM\WebResources\WebResources\new\uscripts\Payment.ts 498处于活动状态
constother2:Promise=test2(newdog(),(d)=>{returnpromise.resolve(d.b);});
我明白

函数使用给定的
动物有条件地调用给定的
func
。如果给狗,则返回类型
T
。如果给予其他动物,则返回类型
Foo

表示参数
func
接受所有
Animal
输入,但根据其输入是否为
Dog
返回不同类型。这意味着我要将
func
声明为以下重载类型:

type AnimalFunc<T> = {
    (dog: Dog): T;
    (animal: Animal): Foo<T>;
}
希望有帮助


更新1 @达里尔:


这适用于定义,但不适用于调用站点。如果我传入一个dog作为第一个参数,我的函数必须接受一个dog并返回一个T,否则它必须接受一个animal并返回一个Foo,在调用站点,它会抱怨函数没有返回其他类型(T或Foo)

如果不知道您的所有用例,我无法说出最好的定义是什么。如果您真的有一个
AnimalFunc
类型的函数,它应该可以工作:

function func1(dog: Dog): string;    
function func1(animal: Animal): Foo<string>;
function func1(animal: Animal): string | Foo<string> {
  if (animal instanceof Dog) {
    return "woof";
  }
  return new Foo<string>();
};

var dog: Dog = new Dog();
var cat: Animal = new Animal();
var dogTest: string = test(dog, func1);
var catTest: Foo<string> = test(cat, func1);
注意,
test3
(前两行)的声明是为了调用方的利益而键入的,而实现(第三行)是为了实现者的利益而键入的。如果您所关心的只是调用
test3
的人的类型安全,但是您的实现足够安全,您不需要TS为您验证类型,那么您可以将其实现为:

function test3<T>(dog: Dog, func: (dog: Dog) => Promise<T>): Promise<T>;
function test3<T>(animal: Animal, func: (animal: Animal) => Promise<Foo<T>>): Promise<Foo<T>>;
function test3(animal: any, func: any): any {
  return func(animal); // fine, but even return animal(func) would be accepted here, to disastrous results at runtime
}
这将导致第一个重载声明出现问题,因为它永远不会返回
承诺


我希望这有帮助

这适用于定义,但不适用于调用站点。如果我传入一只狗作为第一个参数,我的函数必须接受一只狗并返回一个T,否则它必须接受一只动物并返回一个Foo,在调用站点,它抱怨函数没有返回其他类型(T或Foo)啊,我实际上是在返回承诺,这对我来说是一团糟,但我不知道如何修复它。我更新了我的答案,用了一个有效的例子。太棒了。您基本上拥有我所拥有的,但我没有意识到您不必为重载定义泛型类型。这确实使它更简单。我要提出的另一个建议是使用
Promise
vs
Promise | Promise
function test3<T>(dog: Dog, func: (dog: Dog) => Promise<T>): Promise<T>;
function test3<T>(animal: Animal, func: (animal: Animal) => Promise<Foo<T>>): Promise<Foo<T>>;
function test3<T, A extends Animal>(animal: A, func: (animal: A) => Promise<T> | Promise<Foo<T>>): Promise<T> | Promise<Foo<T>> {
  return func(animal);
}
function test3<T>(dog: Dog, func: (dog: Dog) => Promise<T>): Promise<T>;
function test3<T>(animal: Animal, func: (animal: Animal) => Promise<Foo<T>>): Promise<Foo<T>>;
function test3(animal: any, func: any): any {
  return func(animal); // fine, but even return animal(func) would be accepted here, to disastrous results at runtime
}
function test3<T, A extends Animal>(animal: A, func: (animal: A) => Promise<T> | Promise<Foo<T>>): Promise<T> | Promise<Foo<T>> {
  return Promise.resolve(new Foo<T>()); // no error!!
}