打字稿:在对象内推断通用对象的类型

Posted

技术标签:

【中文标题】打字稿:在对象内推断通用对象的类型【英文标题】:Typescript: Infer type of generic object, within object 【发布时间】:2018-09-19 03:04:25 【问题描述】:

我有以下几种:

export type SchemaEntry<A extends object, B> =
  | Validator<B>
  | ((obj: A) => Validator<B>);
export type Schema<A extends object> =  [k in keyof A]: SchemaEntry<A, A[k]> ;

以及使用它们的函数:

function foo<A extends object>(f: Schema<A>): A 
  return undefined as any;

我的问题是当我调用函数时:

const a = foo(
  b: new Validator<number>(),
  c: (o) => new Validator<number>()
);

o 的类型在这种情况下将是 any,而不是我预期的 b: number, c: number。 但是a 确实收到了正确的类型,b: number, c: number

有没有一种方法可以帮助 typescript 推断我的匿名函数的类型?

【问题讨论】:

这里有一个answer to a similar question,它说明了它为什么不起作用:如果它需要推断的类型是泛型或依赖于泛型参数,则无法进行函数参数推断。 谢谢。希望我能以同样的方式解决它! :( 【参考方案1】:

类型推断从参数值流向函数,而不是相反。 foo 看到您传入的参数适用于参数约束并因此允许它,但它不会为您追溯键入无类型的对象。

考虑一下你是否写过:

const input = 
  b: new Validator<number>(),
  c: (o) => new Validator<number>()
;

const a = foo(input);

在调用foo 之后,您不会期望input 的类型会发生变化。

如果你想帮助 typescript 理解 o 的类型,你需要通过直接输入来帮助它理解你正在创建的输入对象的严格类型。

这样做还可以让您不必显式键入&lt;number&gt;Validator 泛型,因为这也应该从整体类型中推断出来。

我建议尝试编写我上面写的代码,但给它一个特定的类型const input: &lt;Your_Type_Here&gt; = ...

【讨论】:

是的,这确实有道理。我确实希望它可以以某种方式完成.. :p 我的意思是。我可以按你说的写类型。 const input: b: Validator&lt;number&gt;, c: (o: b: number, c:number ) =&gt; Validator&lt;number&gt; 。我明确输入Validator 的唯一原因是为了这个sn-p。在我的实际实现中我不必这样做,因为它是具有返回类型的函数调用。我想避免输入inputo。一旦我尝试输入o,它就会告诉我必须可以分配给b: number, c:number

以上是关于打字稿:在对象内推断通用对象的类型的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:如何制作接受对象的类型,其键匹配通用但所有值都是值参数的映射函数

打字稿中的通用对象类型

如何使用打字稿中的查找来推断类型化的 mapValues?

打字稿推断传递了通用参数

打字稿中具有通用键的对象

TypeScript 中对象字面量的动态泛型类型推断