是否可以将 Map 键提取为 TypeScript 中的类型?

塞巴斯蒂安·马雷斯

在 TypeScript 中你可以做

const obj = {
  '123-123': 1,
  '456-456': 2,
}

type objKeys = keyof typeof obj

并且objKeys是联合类型'123-123' | '456-456'

obj如果不是一个对象,而是一个地图,是否有类似的可能?

const map = new Map<string, number>([
  ['123-123', 1],
  ['456-456', 2],
])

type mapKeys = ???
杰卡尔兹

如果你写new Map<string, number>(...),那么你明确地给出了Map一个string键类型,这意味着它将允许你set()get()字符串值的键。如果要将键限制为字符串文字类型的特定联合,则需要更改构造. 例如,如果您提前定义,则可以使用它来代替MapMapKeysstring

type MapKeys = '123-123' | '456-456';
const map = new Map<MapKeys, number>([
  ['123-123', 1],
  ['456-456', 2],
]);

但这有点多余,并且无论如何都与您的要求相反。您希望编译器从传递给构造函数的参数中进行推断。 MapKeysMap


既然你说用例是为了Map保持不变(所以不仅它的键受到约束,而且它的值也不会改变),那么TypeScript 提供ReadonlyMap<K, V>接口可能会更好地为你服务。在运行时没有ReadonlyMap,但 TypeScript 编译器将允许您将Map实例分配给 type 的变量ReadonlyMap

如果我们希望编译器推断MapKeys,我们可能希望将构造函数的键类型限制string为,这给编译器一个字符串的提示。

这两个都意味着创建新ReadonlyMap<K, V>whereK的辅助函数string将有所帮助:

function ReadonlyMapWithStringKeys<K extends string, V>(
  iterable: Iterable<[K, V]>): ReadonlyMap<K, V> {
  return new Map(iterable)
}

const map = ReadonlyMapWithStringKeys([
  ['123-123', 1],
  ['456-456', 2],
])
// const map: ReadonlyMap<"123-123" | "456-456", number>

现在我们可以看到它map的键是强类型的。我们现在可以MapKeys从中定义。有多种方法可以做到这一点;一种是对关键字使用条件类型推断infer

type MapKeys = typeof map extends ReadonlyMap<infer K, any> ? K : never;
// type MapKeys = "123-123" | "456-456"

或者您可以使用类型之类的实用程序Parameters<T>类型来询问编译器的第一个参数map.get()是什么:

type MapKeys = Parameters<typeof map["get"]>[0]
// type MapKeys = "123-123" | "456-456"

Playground 代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TypeScript:将Map中的键用作类型

是否可以从参数中提取键以进行Typescript中的类型推断?

TypeScript中是否可以直接从对象的键创建新类型?

是否可以在TypeScript类型和通用键类型中混合使用特定类型的键?

是否可以在 Typescript 中为接口定义动态类型?

是否可以在 Typescript 中为数组类型添加描述?

在 TypeScript 中为包含 Map 和其他键的对象创建类型

是否可以在Typescript中提取此类型?

是否可以在TypeScript中推断Record的键?

将记录键类型提取为联合类型

对象中的“键”是否可以作为 Typescript 中的类型保护?

是否可以在TypeScript中创建类型或接口为带有正好“ n”个条目的Array?

有什么方法可以检查对象是否为TypeScript中的枚举类型?

是否可以使用 TypeScript 在 Vue.js 中为 ref 值设置联合类型?

对象作为Typescript中的Map键

是否可以将ES6类用作Typescript类型?

如何在JavaScript中检查值是否为Map类型?

Map 可以将键作为自定义类型吗?

是否可以将变量值用作Typescript中的联合类型之一?

在Typescript中,是否可以将数组的每个元素映射到不同的类型?

在TypeScript中是否可以将强类型函数作为参数?

是否可以将构造函数用作TypeScript中另一个函数的参数类型?

TypeScript:从类型/减法类型中删除键

如何在Typescript中为Map的类型别名定义索引签名?

如何在 TypeScript 中为函数类型添加键?

Typescript 类型,用于检查给定键是否作为对象的键传递给解析为数组

是否可以将行类型为X的记录插入行类型为Y的表中?

是否可以将较大类型的部分提取为子类型?

是否可以将Typescript接口导出为方法的输出?