简体   繁体   English

在TypeScript中使用不同参数类型覆盖函数的正确方法

[英]proper way to override function with different param types in TypeScript

TL;DR; TL; DR; my formatAPI function below is very much not the TYpeScript way of overriding a function... 我下面的formatAPI函数几乎不是 TYpeScript覆盖函数的方式...

I've got a function that might be called either of following four ways in JavaScript: 我有一个可以在JavaScript中通过以下四种方式之一调用的函数:

jsf.format("format", function(){ return ... }); // string, function

jsf.format("format"); // string

jsf.format({
  "format1": function(){ return ... },
  "format2": function(){ return ... }
}); // map[string:function]

jsf.format(); // no params

Each signature executes different logic beneath. 每个签名执行下面的不同逻辑。 CUrrently I've got the following: 目前,我有以下内容:

function formatAPI(name: string, callback?: Function): any {
  if (callback) {
    registry.register(name, callback);
  } else if (typeof name === 'object') {
    registry.registerMany(name);
  } else if (name) {
    return registry.get(name);
  } else {
    return registry.list();
  }
}

but it's inconsistent - eg second parameter is string . 但是不一致-例如,第二个参数是string When I change it to string|Object than it fails on my logic ( registry.register(name, callback); - name here has to be a string and string|Object is not assignable to string). 当我将其更改为string|Object ,它在我的逻辑上就失败了( registry.register(name, callback); -这里的name必须是字符串,并且string|Object无法分配给string)。 I'm trying to find a clear and extensible solution (to be able to add more variations if I need to, in the future), I try to adapt another question but I fail. 我试图找到一个清晰且可扩展的解决方案(以便将来能够根据需要添加更多的变体),但是我尝试适应另一个问题,但失败了。

I would appreciate help and/or advise on how should I declare all possible signatures for this function AND the function body. 我将不胜感激,并且/或者建议我应该如何声明该函数和函数体的所有可能签名。

It slices! 切成薄片! it dices! 它切成小方块! It makes toast! 它烤面包!

// Signatures
function formatAPI(): string[];
function formatAPI(name: string): string;
function formatAPI(name: string, callback: (arg: string) => void): void;
function formatAPI(map: { [name: string]: () => string }): void;
// Implementation
function formatAPI(nameOrMap?: string | { [name: string]: () => string }, callback?:(arg: string) => void): string | string[] | void {
  if (typeof nameOrMap === 'string') {
    if (callback) {
      return registry.register(nameOrMap, callback);
    } else {
      return registry.get(nameOrMap);
    }
  } else if (...) {
    // Keep adding checks here
  }
}

One thing to note is that the compiler doesn't use the signatures to infer behavior for type guards. 要注意的一件事是,编译器不使用签名来推断类型防护的行为。 This means you should structure your code slightly more conservatively -- here, I put both string cases inside the typeof check. 这意味着您应该更加保守地构造代码-在这里,我将两个string放在了typeof检查中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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