TypeScript 中的类型推断在特殊用例中无法正常工作

Posted

技术标签:

【中文标题】TypeScript 中的类型推断在特殊用例中无法正常工作【英文标题】:Type inference in TypeScript not working as desired in a special use case 【发布时间】:2019-07-18 07:23:48 【问题描述】:

TypeScript 中的类型推断非常棒。 尽管如此,我有一个案例,我认为 TypeScript 可以推断出相应的类型,但事实并非如此。现在我问自己,在那个特定的用例中,TypeScript 是否不可能做到这一点,或者我做错了什么(或者至少必须改变一些东西才能让它工作)。

实际上,在以下示例中(一个非常简单且很小的商店实现),我想摆脱那个显式的 type Store = ... 声明,并想用 createStore(...) 替换那个 createStore<Store>(...),因为我认为那种类型应该由下面的返回值来推断。这有可能吗?

function createStore<T>(init: (self: T) => T): T 
  // just ignore that this is not implemented here


type Store = 
  count: number,
  increment(): void


// I want to get rid of <Store> in the following line - any ideas?
const store = createStore<Store>(self => 
  return  
    count: 0,

    increment() 
      self.count++
      
  
)

console.log(store.count) // prints out 0
store.increment()
console.log(store.count) // prints out 1

如果工作演示可能有所帮助,请参阅: https://stackblitz.com/edit/typescript-huvdpc


[编辑] 仅供参考,在这个用例中使用流类型推断似乎可以正常工作:

/* @flow */

function createStore<T>(init: (self: T) => T): T 
  const ret: T = ((: any): T)
  Object.assign(ret, init(ret))
  return ret


const store = createStore(self => 
  return 
     count: 0,

     increment() 
       self.count++
     
  
)

console.log(store.count) // prints out 0
store.increment()
console.log(store.count) // prints out 1

[编辑:几个小时后]

从下面的 cmets 来看,似乎无法按照我在上面的示例中想要的方式实现类型推断。

在不同的实现中,类型推断按需要工作,这基本上是相同的:

https://stackblitz.com/edit/typescript-7olxbc

【问题讨论】:

“我想摆脱那种显式” --- 如果你删除显式的 Store 类型 - 那么就不可能输入 self:什么能保证它有一个 @ 987654331@房产? 不可能,只是继续传递Store类型参数,这里似乎完全可以。 非常感谢 zerkms 和 NurbolAlpysbayev 的回答。这意味着我必须以某种方式重构这些东西。我添加了一个新实现的链接,该实现支持上述摘要所需的类型推断:stackblitz.com/edit/typescript-7olxbc 你可以在const store: Store 上移动类型注解,仅此而已。 【参考方案1】:

如果函数具有上述示例中的“参数”-“返回值”-循环性,Typescript 不支持类型推断(至少在当前版本 3.3.x 中不支持)。

不过,Flow 支持这种类型推断。

【讨论】:

以上是关于TypeScript 中的类型推断在特殊用例中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 推断的泛型类型在条件类型中是未知的

TypeScript 无法在扩展语法函数调用中推断数组类型

无法从 TypeScript 反射系统推断 GraphQL 类型

Typescript编译器无法从Promise resolve调用中推断类型

条件类型中的 TypeScript 类型推断

使用联合类型进行类型推断 - 不存在最佳通用类型