TypeScript:返回与参数相同的类型

时间:2019-08-16 17:46:40

标签: typescript typescript-typings typescript-generics

formatISODate函数需要字符串值。

如果不是未定义的话,有很多字符串需要转换。 我可以这样做:

{
  date1: date1 ? formatISODate(date1) : undefined,
  date2: date2 ? formatISODate(date2) : undefined
  ...
}

为避免重复相同的三元表达式,我在下面编写了函数。

function convertDate<T extends string | undefined>(isoDate?: string): T {
  return isoDate ? formatISODate(isoDate) : undefined;
}

但是它有类型错误。

错误:'undefined'可分配给类型'T'的约束,但是'T'可以用约束'string |的另一个子类型实例化。未定义”。

是否可以解决此用例的类型问题?

1 个答案:

答案 0 :(得分:3)

让这个例子更加容易。

function convertDate<T extends string | undefined>(isoDate?: string): T {
   return undefined
}
  

'undefined'可分配给类型'T'的约束

均值:函数(undefined)返回的内容与泛型类型参数T(extends string | undefined)的约束相匹配。

  

,但是可以使用约束'string |的其他子类型实例化'T'。未定义”。

方法:TypeScript认为这样做不安全。如果您在编译时定义了这样的函数,该怎么办:

// expects string return type according to generics
// but you return undefined in function body
const res = convertDate<string>("2019-08-16T16:48:33Z")

然后根据您的签名,您期望返回类型为字符串。但是在运行时情况并非如此!可以用与您在函数(string中返回的子类型不同的子类型(此处为undefined)实例化T的差异用TypeScript错误表示。

可能的解决方案:

说服编译器的唯一方法是强制转换返回类型:

declare function formatISODate(d: string): string

function convertDate<T extends string | undefined>(isoDate?: string): T {
  return (isoDate ? formatISODate(isoDate) : undefined) as T
}

但是我不确定,如果您真的想要那样。泛型类型参数在函数中定义的方式几乎没有用,因为它没有在参数中使用。为什么不写

function convertDate(isoDate?: string): string | undefined {
  return isoDate ? formatISODate(isoDate) : undefined;
}

如果您的目标只是避免重复相同的三元表达式,则可以使用上述代码来实现。