TypeScript中的通用函数生成器生成的函数返回类型无法分配

时间:2018-11-20 14:51:33

标签: typescript

当我运行此代码时:

type Converter<T extends ConverterOutput> = (value: string) => T
type ConverterOutput = number | string

function generateConverter<T extends ConverterOutput>(
  value: string,
  type: 'number' | 'string'
): Converter<T> {
  return (value: string): T => {
    switch (type) {
      case 'number':
        return Number(value)

      default:
        return value
    }
  }
}

我得到了这些2 errors

  • [ts] Type 'number' is not assignable to type 'T'. [2322]
  • [ts] Type 'string' is not assignable to type 'T'. [2322]

表示2个switch ... case返回值。由于T扩展了ConverterOutput,而number | string本身就是return <U extends T>(value: string): U => {,因此我在这段代码中没有什么错误。

我尝试添加一个通用捕获:U,但是除了告诉我这次不能分配给List<RMH> results = data1.Where(d => d.Name == "HPBaxxter"); 之外,它没有解决任何其他问题。

2 个答案:

答案 0 :(得分:2)

Typescript不允许您在期望通用类型参数值的地方分配具体值。这样做的原因是通常无法针对可以为泛型类型参数传递的所有可能的派生类型来验证值。例如,即使在您的情况下,T extends number| string也是如此,这意味着它可能是数字文字类型1,而值Number(value)无法满足要求。

在您的情况下,我建议您取消使用泛型类型参数,并使用多个重载,将实现签名返回Converter<number | string>。这样做还有一个好处,就是只需将转换器的类型指定为字符串即可,而不必同时指定为string和type参数。

type Converter<T extends ConverterOutput> = (value: string) => T
type ConverterOutput = number | string


function generateConverter(value: string, type: 'number'): Converter<number> 
function generateConverter(value: string, type: 'string'): Converter<string> 
function generateConverter(value: string, type: 'number' | 'string'): Converter<number | string> {
  return (value) => {
    switch (type) {
      case 'number':
        return Number(value)

      default:
        return value
    }
  }
}

答案 1 :(得分:1)

因为numberstring本身都不扩展。这就是为什么它不起作用。您可以通过直接指定类型来解决此问题,例如

function generateConverter(value: string, type: 'number' | 'string'): Converter<ConverterOutput> {
    return (value: string): ConverterOutput => {
        switch (type) {
            case 'number':
                return Number(value)

            default:
                return value
        }
    }
}