打字稿、泛型和重载

Posted

技术标签:

【中文标题】打字稿、泛型和重载【英文标题】:Typescript, generics and overloading 【发布时间】:2021-10-04 13:59:30 【问题描述】:

我正在努力在 Typescript 中实现一些我想重载的函数,这些函数也使用泛型。我被这个结果彻底搞糊涂了:

*请注意,我已经删除了不会导致问题的代码,所以请忽略实际功能的无用处。

这行得通:

export function persistContactData<T>(
  contactData: T,
  callback?: () => void
): void;
export function persistContactData<T>(
   contactData :  contactData: T ,
  callback?: () => void
): void;
export function persistContactData<T>(
   contactData :  contactData: T ,
  callback?: () => void
) 
  // implementation

这没有(只有第一个有错误):


// *** Compile error: "This overload signature is not compatible with its implementation"
//
export function getPersistedContactData<T>(
  contactId: string,
  callback: (result?: T) => void
): void;

// No more errors, and if I remove the above signature everything is fine.
export function getPersistedContactData<T>(
   contactId :  contactId: string ,
  callback: (result?: T) => void
): void;
export function getPersistedContactData<T>(
   contactId :  contactId: string ,
  callback: (result?: T) => void
) 
  // implementation

我对这里的问题感到困惑,但我猜测通用参数是如何使用的?但这似乎不应该有所作为。

(我使用的是 Typescript 3.9.3)

编辑:我更新时没有任何未知类型

【问题讨论】:

什么是PersistContactData?如果它很重要,你能给出它的定义吗?如果它不重要,你可以删除它吗?理想情况下,当您的示例代码被放入像 The TypeScript Playground (link) 这样的独立 IDE 中时,唯一存在的问题应该是您要询问的问题。 如果我调用getPersistedContactData("foo", x =&gt; x);,您希望getPersistedContactData() 的实现中的contactId 变量是什么?它不会是string"foo" 的值没有 contactId 属性,所以你在做一些奇怪的事情。不知道那是什么意思,但你应该修复它like this maybe... 如果这没有帮助,你可能想在问题中详细说明你想要做什么。祝你好运! 好点,我已经删除了所有不必要和未定义的类型,所以现在应该更容易看到这个问题。 【参考方案1】:

问题在于泛型参数让编译器假设形状可能定义预期类型,因为实际实现将定义实际参数形状。

如果删除所有泛型并使用实际类型,则可以看到这一点。

这会起作用(但实际上可能不是预期的):

export function persistContactData<T>(
  contactData: T,  // <---- What is T?  ┐( ̄~ ̄)┌  Could be the right shape?
  callback?: () => void
): void;
export function persistContactData<T>(
   contactData :  contactData: T ,
  callback?: () => void
): void;
export function persistContactData<T>(
   contactData :  contactData: T ,
  callback?: () => void
) 
  // implementation

这不会:

// Error
export function persistContactData(
  contactData: string,  // <---- string is not compatible with the implementation
  callback?: () => void
): void;
export function persistContactData(
   contactData :  contactData: string ,
  callback?: () => void
): void;
export function persistContactData(
   contactData :  contactData: string ,
  callback?: () => void
) 
  // implementation

【讨论】:

以上是关于打字稿、泛型和重载的主要内容,如果未能解决你的问题,请参考以下文章

再次:打字稿函数重载

打字稿getter / setter重载

打字稿泛型返回类型

打字稿泛型-“扩展对象”毫无意义吗?最佳做法是啥?

打字稿承诺泛型类型

打字稿重载、可选参数和类型推断