函数由参数决定返回类型

时间:2019-04-17 07:27:55

标签: javascript typescript function

我有两个界面:

interface ChildConfig {
  x: number;
  y: number;
}
interface Config {
  [name: string]: ChildConfig;
}

我想要一个具有可选参数的函数。当参数存在时,我希望函数返回ChildConfig,否则,我希望返回Config

function getConfig(name?: string): ??? {
  if (name) return config[name];
  return config;
};

我该怎么办?

3 个答案:

答案 0 :(得分:1)

对于每个the docs,您可以使用函数重载来真正使这种类型安全:

function getConfig(): Config
function getConfig(name: string): ChildConfig
function getConfig(name?: string): Config | ChildConfig {
  if (name) {
    return config[name];
  }
  return config;
};

现在,根据您的调用方式,返回类型将有所不同,并且仅使用联合类型(例如)时,您将无需使用as断言或类型保护来确定返回的内容Config | ChildConfig

答案 1 :(得分:0)

尝试这样的事情

function getConfig(name?: string): ChildConfig|Config {
  if (name) return config[name];
  return config;
};

答案 2 :(得分:0)

要与其他答案区分开来,提供另一种可能的方法,可以将返回类型设置为Config|ChildConfig

interface ChildConfig {
  x: number;
  y: number;
}
interface Config {
  [name: string]: ChildConfig;
}

const config = {} as any;

function getConfig(name?: string): Config|ChildConfig {
  if (name) return config[name];
  return config;
};

用法要求您明确确定返回类型是Config还是ChildConfig,如下所示:

const childConfig = getConfig('myTest') as ChildConfig;

这样,childConfig的类型将为ChildConfig

否则,您可以将这种机制与类型防护罩(更多here)结合起来

function isChildConfig(arg: any): arg is ChildConfig {
    return arg && arg.x && arg.y;
}

然后仅在子配置下对结果使用类型防护进行操作:

const _config = getConfig('test');
if (isChildConfig(_config)) {
    _config. // <-- intellisense here
}

这将确保_config具有xy属性:

enter image description here

TS Playground