如何定义具有重复结构的打字稿类型?

hyi*_*Yoo 7 javascript typescript

我有一个看起来像这样的类型:

type Location=`${number},${number};${number},${number};...`
Run Code Online (Sandbox Code Playgroud)

是否有类似的实用程序类型Repeat<T>可以为我做到这一点?像这样:

type Location=Repeat<`${number},${number};`>
Run Code Online (Sandbox Code Playgroud)

cap*_*ian 6

仅适用于 TS >=4.5

可以创建独立类型。

请看这个例子:

type Coordinates = `${number},${number};`

type MAXIMUM_ALLOWED_BOUNDARY = 50

type Last<T extends string[]> = T extends [...infer _, infer Last] ? Last : never;

type ConcatPrevious<T extends any[]> = Last<T> extends string ? `${Last<T>}${Coordinates}` : never

type Mapped<
    N extends number,
    Result extends Array<unknown> = [Coordinates],
    > =
    (Result['length'] extends N
        ? Result
        : Mapped<N, [...Result, ConcatPrevious<Result>]>
    )


// type MyLocation = 
// | `${number},${number};` 
// | `${number},${number};${number},${number};` 
// | `${number},${number};${number},${number};${number},${number};` 
// | `${number},${number};${number},${number};${number},${number};${number},${number};` 
// | `${number},${number};${number},${number};${number},${number};${number},${number};${number},${number};` 
// | ... 44 more ... 
// | `${number},${number};${number},${number};${number},${number};${number},${number};${number},${number};${number},${number}; ....

type MyLocation = Mapped<MAXIMUM_ALLOWED_BOUNDARY>[number]

const myLocation1: MyLocation = '45,56;67,68;' // ok
const myLocation2: MyLocation = '45,56;67,68;1,2;3,4;5,6;7,8;9,10;' // ok
const myLocation3: MyLocation = '45,56;67,68;1,2;3,4;5,6;7,8;9,10,' // expected error
Run Code Online (Sandbox Code Playgroud)

操场

Mappedtypes 是代表循环的实用程序类型while。它迭代直到 的长度Result达到N。换句话说Mapped<10>- 将迭代 10 次。看这个纯js的例子:

const mapped = (N: number, Result: any[] = []): string => {
    if (N === Result.length) {
        return Result.join('')
    }
    
    const x = Math.random();
    const y = Math.random()
    return mapped(N, [...Result, `${x},${y};`])
}
Run Code Online (Sandbox Code Playgroud)

在 js 中很难表示联合,这就是我使用join(''). 我希望清楚它是如何工作的。

如果你想增加到MAXIMUM_ALLOWED_BOUNDARY500,它会加热你的 CPU,所以要小心。

正如您可能已经注意到的,在类型脚本中不可能表示类型的递归模式,但可以创建足够大的联合。

请记住,该${number}类型存在一些缺点。您可以使用带前导零的数字,如下所示:

const x: `${number}` = '01'.
Run Code Online (Sandbox Code Playgroud)

有用的链接

  1. 您可以在此处找到如何使用此模式创建数字范围的示例。

  2. 在这里您可以找到引入此功能的 PR

  3. 在这里这里您可以找到与此模式相关的我的文章


Pra*_*mar 0

string如果您愿意,可以直接选择类型:

type myLocation = string;
const myLocation: myLocation = "123123123";

console.log(myLocation);
Run Code Online (Sandbox Code Playgroud)

否则,如果你想缩小范围,那么最好将其声明const为:

const myLocation = "123123123";
console.log(myLocation);
Run Code Online (Sandbox Code Playgroud)

那么你的类型将是myLocation

在此输入图像描述