你能让 TS 从被赋值的值中推断出变量的泛型类型参数吗?

你能让 TS 从被赋值的值中推断出变量的泛型类型参数吗?

问题描述:

回答这个问题 解决方案是在 Map 构造函数上指定类型参数,如下所示:

Answering this question the solution was to specify type arguments on the Map constructor, like this:

const conditions3: ReadonlyMap<string, any> = new Map<string, any>([
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^
    [FirstName.Alex, 'foo'],
    [Lastname.Smith, 'bar']
]);

请注意,OP 想要给 conditions3 类型 ReadonlyMap,而不仅仅是 Map;否则我们可以完全从 conditions3 中删除类型注释.

Note that the OP wanted to give conditions3 the type ReadonlyMap<string, any>, not just a Map<string, any>; otherwise we could have just removed the type annotation from conditions3 entirely.

不幸的是,这意味着在 ReadonlyMapMap 上重复类型参数.

Unfortunately, that means repeating the type arguments on both ReadonlyMap and Map.

一般的情况下,有没有办法告诉 TypeScript 从类型参数中推断出变量/常量类型(在本例中为 ReadonlyMap)的类型参数分配的值(在本例中为 Map)?我的意思不是针对这种特定情况的解决方案(我想我可能有一个函数,也许是一个从字面上提供只读地图的函数,至少在开发版本中),而是一个通用的从目标推断的解决方案?

In the general case, is there a way to tell TypeScript to infer the type arguments for the variable/const's type (ReadonlyMap in this example) from the type arguments on the value being assigned (Map in this example)? I don't mean solutions to this specific case (I think I'd probably have a function, perhaps one that literally provided a read-only map, at least in development builds), but a general infer-from-the-target solution?

我的各种幼稚方法都不起作用(前两个灵感来自 Java 的 <>):

My various naive approaches don't work (the first two inspired by Java's <>):

const conditions3: ReadonlyMap<> = new Map<string, any>([
//                 ^^^^^^^^^^^^^−−−−− Generic type 'ReadonlyMap<K, V>' requires
//                                    2 type argument(s).(2314)
    [FirstName.Alex, 'foo'],
    [Lastname.Smith, 'bar']
]);

操场链接

const conditions3: ReadonlyMap<string, any> = new Map<>([
// Same error with no matching overloads the OP had −^^
    [FirstName.Alex, 'foo'],
    [Lastname.Smith, 'bar']
]);

操场链接

const conditions3: ReadonlyMap = new Map<string, any>([
//                 ^^^^^^^^^^^−−−−− Generic type 'ReadonlyMap<K, V>' requires
//                                  2 type argument(s).(2314)
    [FirstName.Alex, 'foo'],
    [Lastname.Smith, 'bar']
]);

操场链接

在一般情况下是否可以避免重复?

Is the repetition avoidable in the general case?

这是设置代码(所以它在问题中,而不仅仅是链接):

Here's the setup code (so it's in the question, not just linked):

export enum FirstName {
    Alex = 'alex',
    Bob = 'bob'
}
    
export enum Lastname {
    Smith = 'smith',
    Abrams = 'abrams'
} 

不幸的是,变量中的部分推理没有语法.

There is no syntax for partial inference in variables unfortunately.

唯一的解决方法是使用您在评论中提到的函数:

The only work around would be to use a function as you mention in the comments:

function roMap<Key, Value>(map: Map<Key, Value>): ReadonlyMap<Key, Value> { return map; } 

const conditions3 = roMap(new Map<string, any>([
    [FirstName.Alex, 'foo'],
    [Lastname.Smith, 'bar']
]));

游乐场链接