Typescript:从数组类型中检索元素类型信息

Ben*_*ate 22 typescript

假设我有一些数组类型T[],是否可以T在另一个别名/接口中提取类型?例如,我的(假的)理想代码如下:

// for illustration only...

type ArrayElement<T[]> = T;

// then, ArrayElement<string[]> === string
Run Code Online (Sandbox Code Playgroud)

如果不是,是否存在不允许此类运营商的一般类型理论原因?如果没有,我可能会建议添加它.

谢谢!

zil*_*nas 56

通过在括号中写入索引类型可以很容易地实现这一点:

type ArrayElementType = ArrayType[number];
Run Code Online (Sandbox Code Playgroud)

更新

正如下面的评论所建议的,创建通用数组元素类型:

type ArrayElementType<ArrayType extends Array> = ArrayType[number];
Run Code Online (Sandbox Code Playgroud)

PSnumber不是一个值而是一个类型。

  • 这应该是公认的答案。 (2认同)

jer*_*ico 45

另一种选择:

type ArrayElement<A> = A extends readonly (infer T)[] ? T : never
Run Code Online (Sandbox Code Playgroud)


Wil*_*den 22

您可以通过以下方式实现这一目标:

type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];
Run Code Online (Sandbox Code Playgroud)

虽然我亲自给它起了类似的东西ArrayType extends readonly unknown[],因为ArrayType读起来要比它清楚得多readonly unknown[].

  • Typescript 支持基于索引的数组元素类型,例如:`[number,string]`。所以这个答案有一些优点,如`ArrayElement&lt;[number,string]&gt; -&gt; number | 字符串` (5认同)
  • 此实现从数组类型推断元素类型,而接受的答案推断数组中第一个元素的类型.我只是觉得它更优雅,但由于数组保证(通过其类型定义)只包含相同类型的元素,因此使用此解决方案没有技术优势. (4认同)
  • @feihcsim我很确定这个答案不需要改变,原始答案(`ArrayType[number]`)仍然可以正常工作,即使启用了`--noUncheckedIndexedAccess`。该标志不会影响这些类型级别的操作。 (3认同)
  • 我同意@feihcsim。如果启用了“--noUncheckedIndexedAccess”标志,我的答案可能会有问题,而@jerico的答案则不会。这足以让我选择这个答案而不是我的答案,这有点令人难过,因为“ArrayType[number]”更容易阅读,尤其是对于初学者来说。 (2认同)

art*_*tem 17

从2.1开始,typescript支持类型的[]运算符.官方名称是索引访问类型,也称为查找类型,它的工作方式如下:

type A = {a: string, b: number} [];

type AElement = A[0];

let e: AElement = {x: 0}; //error TS2322: Type '{ x: number; }' is not 
                       //assignable to type '{ a: string; b: number; }'
Run Code Online (Sandbox Code Playgroud)

  • 也可以执行“YourArray[number]”,我认为它比“YourArray[0]”更通用 (7认同)

小智 6

另外一个选择:

type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;
Run Code Online (Sandbox Code Playgroud)

您可以在以下位置找到更多信息inferhttps://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types


lbe*_*son 5

实用程序类型库有一个类型https://github.com/piotrwitek/utility-types#valuestypet(以及许多其他类型)

例如

import { ValuesType } from 'utility-types';

type NumberArray = number[];
// Expect: number
type NumberItems = ValuesType<NumberArray>;
Run Code Online (Sandbox Code Playgroud)