首页 > 解决方案 > 如何为具有多种返回类型的重载函数指定类型?

问题描述

以下 TypeScript 代码将无法编译:

interface ZeroFunc {
    (value: string): string;
    (value: number): number;
}

const zero: ZeroFunc = (value: string | number) =>
    typeof value === 'string' ? '' : 0;

错误:

Type '(value: string | number) => "" | 0' is not assignable to type 'ZeroFunc'.
  Type 'string | number' is not assignable to type 'string'.
    Type 'number' is not assignable to type 'string'. ts(2322)

它似乎在抱怨返回类型。

该错误是有道理的,即使该功能已正确实现。

有没有办法正确指定这个函数的类型,而不使用any作为返回类型?

是否有可能正确实现ZeroFunc接口?

编辑:

这是对问题的更好说明:

function zero(value: string): string;
function zero(value: number): number;
function zero(value: string | number): string | number {
    return typeof value === 'string' ? '' : 0;
}

type ZeroFunc = typeof zero;

const zero2: ZeroFunc = (value: string | number): string | number {
    return typeof value === 'string' ? '' : 0;
}

的声明zero2与上面的错误相同。但很明显,它们是完全相同的函数签名。我真的只是复制粘贴它。

该类型ZeroFunc甚至具有与我上面的接口完全相同的定义。

标签: typescriptoverloadingunion-types

解决方案


ZeroFunc 接口有两个方法与最终赋值的右侧不匹配(一个接受字符串或数字并返回字符串或数字的函数)。

我想我会这样做:

interface ZeroFunc {
  (value: string | number): string | number;
}

const zero: ZeroFunc = (value: string | number) => typeof value === 'string' ? '' : 0;

但后来我想知道为什么接口是必要的。你想强制执行什么?

更新

我试图强制如果参数是数字,那么返回类型将是数字。对于字符串参数,返回类型是字符串。

我想知道是否可能如下:

type ZeroFunc<T> = (value: T) => T;

// OK
const zeroString: ZeroFunc<string> = (value: string) => '';
// OK
const zeroNumber: ZeroFunc<number> = (value: number) => 0;

// Bad case caught: 
//   Type '(value: number) => string' is not assignable to type 'ZeroFunc<number>'.
//     Type 'string' is not assignable to type 'number'
const zeroBad: ZeroFunc<number> = (value: number) => '';

// But this is also bad and is NOT caught
const zero: ZeroFunc<string | number> = (value: string | number) => 0;

但似乎不是 - 最后一种情况会编译,因为返回值与类型匹配string | number


推荐阅读