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

Posted

技术标签:

【中文标题】TypeScript:返回与参数相同的类型【英文标题】:TypeScript: Return same type as parameter 【发布时间】:2019-12-23 00:54:21 【问题描述】:

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;

但是它有一个类型错误。

错误:“未定义”可分配给“T”类型的约束,但“T”可以用约束“字符串|”的不同子类型实例化。未定义'。

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

【问题讨论】:

formatISODate 有类型参数吗?如果不是,我不确定 T 给你买了什么。这个函数应该只返回 formatISODate | 的返回值。未定义 formatISODate 确实有类型,即它需要字符串并返回字符串。 return string | undefined 将在使用 date1: convertDate(date1) 时显示类型错误,如果 date1 严格来说是一个字符串。 我之前看错了。只需将其键入为 convertDate(isoDate?: string): string。假设您没有在 tsconfig 中启用严格的空检查,这应该可以工作(鉴于您的内联三元组似乎正在工作,我怀疑您是否这样做) 【参考方案1】:

让我们让这个例子更简单。

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

'undefined' 可以赋值给'T'类型的约束

意味着:您在函数中返回的内容 (undefined) 与泛型类型参数 T (extends string | undefined)) 的约束相匹配。

,但 'T' 可以用不同的约束子类型 'string |未定义'。

意味着:TypeScript 不认为这是安全的。如果你在编译时这样定义你的函数会怎样:

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

然后根据您的签名,您希望返回类型是字符串。但在运行时并非如此!可以使用不同于函数 (undefined) 中返回的子类型(此处为 string)来实例化 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;

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

【讨论】:

非常感谢您详细解释它为什么会失败。你是对的,泛型类型参数在这种情况下没有意义。

以上是关于TypeScript:返回与参数相同的类型的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在when语句中返回与type参数相同的类型

TypeScript 中的函数重载与使用联合类型

Typescript构造函数和继承

在 Typescript 中按字符串返回不同的类型

TypeScript 类方法具有与构造函数相同的重载签名

Type[keyof Type] 函数参数的 Typescript 类型保护