【问题标题】:create string literal type from dyanamic array in typescript从打字稿中的动态数组创建字符串文字类型
【发布时间】:2021-10-15 13:14:38
【问题描述】:

我的这段代码非常适合使用 as const 的静态数组

type ScaleKeys<A extends readonly unknown[]> = `${keyof A & `${number}`}x`;

const spacing = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4] as const;

type SpaceKeys = ScaleKeys<typeof spacing>; // works great with a static array

const a: SpaceKeys = '0x';

但是必须静态声明一个大的静态数组并不是很好。

是否可以用动态数组来做到这一点:

我试过了:

type ScaleKeys<A extends readonly unknown[]> = `${keyof A & `${number}`}x`;

const b: ReadonlyArray<number> = Array.from({ length: 20 });

type C = ScaleKeys<typeof b> // not sure if this is even possible

这是一个playground,上面有。

【问题讨论】:

  • 您对ScaleKeys&lt;typeof b&gt; 有什么期望? ${number}px?
  • @captain-yossarian 字符串联合'1x' | '2x' | '3x' .... 等到 '20x'
  • 一旦b 只是一个ReadonlyArray&lt;number&gt;,编译器不知道它有多长。您可以告诉CScaleKeys&lt;TupleLen&lt;20&gt;&gt; 用于适当定义的TupleLen 类型,例如this code,但编译器无法跟踪20你写的代码。如果我提供的代码满足您的需求,我可以写一个答案;否则请在minimal reproducible example 中描述失败的用例。

标签: typescript tuples


【解决方案1】:

如果你想动态创建元组,你可以使用这个工具类型:

type Tuple<N extends number, Cache extends number[] = []> = Cache['length'] extends N ? Cache : Tuple<N, [...Cache, Cache['length']]>

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
type Result = Tuple<20>

如果你想映射它,考虑这个函数:



type Tuple<N extends number, Cache extends number[] = []> = Cache['length'] extends N ? Cache : Tuple<N, [...Cache, Cache['length']]>

type MapTuple<T extends ReadonlyArray<number>> = {
    [Prop in keyof T]: `${Prop & string}x`
}

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
type Result = Tuple<20>

const tuple = <Length extends number>(length: Length) =>
    new Array(length)
        .fill(0)
        .map((_, index): `${number}x` => `${index}x`) as unknown as MapTuple<Tuple<Length>>

// ["0x", "1x", "2x",... "41x"]
const result = tuple(42)

Playgrund

如果你对元组操作感兴趣,可以查看我的blog

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-03
    • 2021-12-13
    • 1970-01-01
    • 2018-04-28
    • 2021-11-06
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多