为什么此映射类型丢失对象文字的类型推断?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么此映射类型丢失对象文字的类型推断?相关的知识,希望对你有一定的参考价值。

这是人为的,但通常我可以将对象文字传递给函数,并以通用的方式(即:]捕获文字的值:>

type Values<V> = {
  a: V;
  b: V;
};

function mapValues<V>(v: Values<V>): V {
  return v as any; // ignore
}
const vn = mapValues({ a: 1, b: 2 }); // inferred number
const vs = mapValues({ a: '1', b: '2' }); // inferred string

取决于我传递给vn的内容,vsnumber都正确地推断为stringmapValues。>

这甚至适用于索引类型:

function mapValues2<V>(v: { [key: string]: V }): V {
  return v as any;
}
const v2n = mapValues2({ a: 1, b: 2 }); // inferred number
const v2s = mapValues2({ a: '1', b: '2' }); // inferred string

v对象文字知道它的值分别是string / number,并且我能够捕获推断出的V并将其用于返回类型。

但是,一旦我使用了映射类型,即:

enum Foo {
  a,
  b,
}
function mapValues3<K, V>(o: K, v: { [key in keyof K]: V }): V {
  return v as any;
}
const v3n = mapValues3(Foo, { a: 1, b: 2 }); // inferred unknown
const v3s = mapValues3(Foo, { a: '1', b: '2' }); // inferred unknown

就像V分别忘记了它是string / number,而我得出unknown的推论。

请注意,如果我显式键入const v3n: number则可以,但是我想依靠类型推断为我找出V

我很困惑,为什么将[key: string]从第二个片段更改为第三个中的[key in keyof K]会影响对象文字类型推断的: V侧的推断。

有什么想法吗?

这是人为的,但通常我可以将对象文字传递给函数,并以通用方式捕获文字的值,即:type Values = {a:V; b:V; };函数mapValues&...

答案

对于此失败的原因,我没有一个规范的答案。我的直觉是,您试图使mapValue3(o, v)的键和值都取决于v参数的键,将o的推论推迟到显然也是如此后来,编译器放弃了其一般的V推论。

[通常,您会遇到类型unknown的值val并试图从中推断出相关类型U的情况。也就是说,您将T视为某些类型函数UF<T>,并且希望编译器从F推断T。假设anyone

以上是关于为什么此映射类型丢失对象文字的类型推断?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 TypeScript 字符串枚举适用于字符串文字并正确进行类型推断

为啥泛型 T 仅在具有约束时才被推断为文字类型?

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

推断类型var

文字类型推断 - 打字稿

为啥 Rust 不能推断出 Iterator::sum 的结果类型?