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

时间:2016-12-21 00:20:50

标签: typescript

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

// for illustration only...

type ArrayElement<T[]> = T;

// then, ArrayElement<string[]> === string

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

谢谢!

6 个答案:

答案 0 :(得分:12)

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

type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];

因此这些示例将起作用:

type X = ArrayElement<string[]>; // string
type Y = ArrayElement<readonly string[]>; // string
type Z = ArrayElement<[string, number]>; // string | number

说明

ArrayType extends readonly unknown[]说,我们希望类型参数ArrayType至少是一个只读数组(它也接受可变数组),以便我们可以查看其元素类型。

请注意,readonly unknown[]是TypeScript 3.4中添加的语法;对于早期版本,请使用ReadonlyArray<unknown>

在右侧,ArrayType[number]表示可通过数字索引访问的数组中的任何值-即数组中的任何值。

答案 1 :(得分:10)

从2.1开始,typescript支持类型的[]运算符。官方名称是indexed access types, also called lookup types,它的工作原理如下:

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; }'

答案 2 :(得分:4)

另一种选择:

type ArrayElement<A> = A extends readonly (infer T)[] ? T : never

答案 3 :(得分:1)

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

例如

import { ValuesType } from 'utility-types';

type NumberArray = number[];
// Expect: number
type NumberItems = ValuesType<NumberArray>;

答案 4 :(得分:1)

根据此问题答案下方的评论之一中的 3nuc 答案,最简单的方法是:

type ArrayElementType = ArrayElements[number];

答案 5 :(得分:0)

另一种选择:

type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;

您可以在以下网址找到有关 infer 的更多信息: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types