typescript - 将基于 Tuple 的类型提取到新的 Tuple
问题描述
假设我有一个字符串元组:
const tuple = ["a", "b", ..., "n"] as const;
映射到某个类型的条目:
type MyType = {
a: string;
b: number;
...
n: N;
如何将位于的类型提取Mytype[typeof tuple[number]]
到一个新的元组中,结果是:
type MyTypeToTuple = [Mytype[tuple[0]], Mytype[tuple[1]], ... , Mytype[tuple[n]]]
?
解决方案
You can use mapped types to turn tuples into tuples. Unfortunately, the following straightforward implementation won't work:
type MyTuple = typeof tuple;
type Oops = { [K in keyof MyTuple]: MyType[MyTuple[K]] } // error
// -------------------------------> ~~~~~~~~~~~~~~~~~~
// Type 'readonly ["a", "b", "n"][K]' cannot be used to index type 'MyType'.(2536)
//
/* type Oops = {
[x: number]: string | number | N;
readonly 0: string;
readonly 1: number;
readonly 2: N;
length: unknown;
toString: unknown;
toLocaleString: unknown; ... */
That's because of a bug or limitation in TypeScript whereby the tuple/array mapping isn't triggered on specific tuple types like MyTuple
; see microsoft/TypeScript#27995. For now, you need to do it on an unspecified generic type parameter like T extends MyTuple
, and even then the compiler cannot understand that the K
in T[K]
only includes the numeric indices and therefore that T[K] extends keyof MyType
. Thus, instead of MyType[T[K]]
you need something like MyType[Extract<T[K], keyof MyType>]
with the Extract<T, U>
utility type to calm the compiler's worries. Thus we have the two-line definition:
type MapToMyType<T> = { [K in keyof T]: MyType[Extract<T[K], keyof MyType>] };
type MyTypeToTuple = MapToMyType<typeof tuple>
// type MyTypeToTuple = readonly [string, number, /*...*/ N]
Which is now the type you want.
推荐阅读
- php - 如何使用外键约束 laravel 播种表
- javascript - Moment.Js 日期到星期和年份
- java - 即使在节能器打开/振动禁用时强制振动
- python-3.x - 替换for循环计数器Python的函数
- java - 我可以使用 jgit fetch() 克隆 git 存储库吗?
- vue.js - Quasar 扩展项:如何为选择的子菜单赋予不同的颜色?
- powershell - 来自 CSV 导入的多值数组 - 交换权限
- docker - jmxterm:Docker 容器内的“无法创建系统终端”
- java - 使用 Spring Boot LaunchScript 时如何获取当前工作目录
- swift - TextEditor 更改时 UI 不刷新