Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 获取数组文本的索引类型_Typescript - Fatal编程技术网

Typescript 获取数组文本的索引类型

Typescript 获取数组文本的索引类型,typescript,Typescript,假设我有以下数组文字: const list = ['foo', 'bar', 'baz'] as const; 我试图生成一个类型,它表示这个数组的可能索引。我试图实现以下目标: const list = ['foo', 'bar', 'baz'] as const; type ListIndex = Exclude<keyof (typeof list), keyof []>; const list=['foo','bar','baz']作为const; 类型ListInd

假设我有以下数组文字:

const list = ['foo', 'bar', 'baz'] as const;
我试图生成一个类型,它表示这个数组的可能索引。我试图实现以下目标:

const list = ['foo', 'bar', 'baz'] as const;

type ListIndex = Exclude<keyof (typeof list), keyof []>;
const list=['foo','bar','baz']作为const;
类型ListIndex=排除;
但是
ListIndex
现在变成了
“0”|“1”|“2”
,而不是
0 | 1 | 2

谁能告诉我如何获得所需的
0 | 1 | 2
类型吗?

您得到的是。但我们可以通过一些映射技巧来实现您所需要的:

const list = ['foo', 'bar', 'baz'] as const;

type StrNum = {
  "0": 0,
  "1": 1,
  "2": 2,
  "3": 3,
  "4": 4 // if your tuple will be longer extend this for it
}

type MapToNum<A extends keyof StrNum> = {
  [K in A]: StrNum[K]
}[A] // this maps string keys into number by using StrNum type

type ListIndex = MapToNum<Exclude<keyof (typeof list), keyof []>>;
// result type 0 | 1 | 2

const list=['foo','bar','baz']作为const;
类型StrNum={
"0": 0,
"1": 1,
"2": 2,
"3": 3,
“4”:4//如果您的元组将更长,请为此扩展此元组
}
类型MapToNum={
[K in A]:StrNum[K]
}[A] //使用StrNum类型将字符串键映射为数字
类型ListIndex=MapToNum;
//结果类型0 | 1 | 2

没有一种内置的方法来实现这一点,这非常烦人。我们正在寻找解决这一问题的方法,但目前我们必须解决这一问题

这就是我在自己的项目中所做的:

/** Type of the elements in an array */
type ElementOf<T> = T extends (infer E)[] ? E : T extends readonly (infer E)[] ? E : never;

/** Used internally for `Tail`. */
type AsFunctionWithArgsOf<T extends unknown[] | readonly unknown[]> = (...args: T) => any;

/** Used internally for `Tail` */
type TailArgs<T> = T extends (x: any, ...args: infer T) => any ? T : never;

/** Elements of an array after the first. */
type Tail<T extends unknown[] | readonly unknown[]> = TailArgs<AsFunctionWithArgsOf<T>>;

/** Used internally for `IndicesOf`; probably useless outside of that. */
type AsDescendingLengths<T extends unknown[] | readonly unknown[]> =
    [] extends T ? [0] :
    [ElementOf<ElementOf<AsDescendingLengths<Tail<T>>[]>>, T['length']];

/** Union of numerical literals corresponding to a tuple's possible indices */
type IndicesOf<T extends unknown[] | readonly unknown[]> =
    number extends T['length'] ? number :
    [] extends T ? never :
    ElementOf<AsDescendingLengths<Tail<T>>>;

您可以使用以下类型:

type Indices<T extends readonly any[]> = Exclude<Partial<T>["length"], T["length"]>

这是有意的,而且是书面设计的。这回答了你的问题吗?所有这些都是为了在索引数组时进行类型检查,这样就不会爆炸吗?我想进一步了解这个问题的背景。
list
是否始终定义为索引类型正上方的常数?为什么不使用字符串枚举?@DexterW当前用例是react组件的类型化属性。组件可以接收一个prop,该prop应该是在主题中某处定义的数组的现有索引(例如prop
marginTop={3}
,其中主题中的数组是
{margins:[0,4,8,16,…])
@KamNadimi感谢这些链接。它没有回答我的问题,但提供了更多的见解。感谢你详尽的回答,但我担心这对我来说是太深入了一步:-)答案可能就在我面前,但是你能用创建实际的数字联合类型的例子更新你的答案吗?数组文本作为输入;对不起,不清楚。它只是
类型ListIndex=indicatesof
。我会把它添加到答案中。谢谢你的回答,如果没有其他更合适的解决方案,它看起来就像一个不错的逃生舱:-)
interface Array<T> {
    /**
     * Returns the index of the first occurrence of a value in an array.
     * @param searchElement The value to locate in the array.
     * @param fromIndex The array index at which to begin the search.
     * If `fromIndex` is omitted, the search starts at index 0.
     * Returns -1 if `searchElement` is not found.
     */
    indexOf<This extends T[], T>(this: This, searchElement: T, fromIndex?: IndicesOf<This>): -1 | IndicesOf<This>;
}

interface ReadonlyArray<T> {
    /**
     * Returns the index of the first occurrence of a value in an array.
     * @param searchElement The value to locate in the array.
     * @param fromIndex The array index at which to begin the search.
     * If `fromIndex` is omitted, the search starts at index 0.
     * Returns -1 if `searchElement` is not found.
     */
    indexOf<This extends readonly T[], T>(this: This, searchElement: T, fromIndex?: IndicesOf<This>): -1 | IndicesOf<This>;
}
type Indices<T extends readonly any[]> = Exclude<Partial<T>["length"], T["length"]>
type Test = Indices<typeof list> // Test = 0 | 1 | 2 // works!