diff --git a/index.d.ts b/index.d.ts index 7d3ec213d..c15322e61 100644 --- a/index.d.ts +++ b/index.d.ts @@ -122,6 +122,7 @@ export type {ArrayIndices} from './source/array-indices'; export type {ArrayValues} from './source/array-values'; export type {ArraySlice} from './source/array-slice'; export type {ArraySplice} from './source/array-splice'; +export type {ArrayElement} from './source/array-element'; export type {SetFieldType} from './source/set-field-type'; export type {Paths} from './source/paths'; export type {SharedUnionFieldsDeep} from './source/shared-union-fields-deep'; diff --git a/readme.md b/readme.md index f4b1164cb..5fd21cace 100644 --- a/readme.md +++ b/readme.md @@ -194,6 +194,7 @@ Click the type names for complete docs. - [`ArrayIndices`](source/array-indices.d.ts) - Provides valid indices for a constant array or tuple. - [`ArrayValues`](source/array-values.d.ts) - Provides all values for a constant array or tuple. - [`ArraySplice`](source/array-splice.d.ts) - Creates a new array type by adding or removing elements at a specified index range in the original array. +- [`ArrayElement`](source/array-element.d.ts) - Extracts the element type of an array or union of arrays. - [`SetFieldType`](source/set-field-type.d.ts) - Create a type that changes the type of the given keys. - [`Paths`](source/paths.d.ts) - Generate a union of all possible paths to properties in the given object. - [`SharedUnionFieldsDeep`](source/shared-union-fields-deep.d.ts) - Create a type with shared fields from a union of object types, deeply traversing nested structures. diff --git a/source/array-element.d.ts b/source/array-element.d.ts new file mode 100644 index 000000000..53a30a134 --- /dev/null +++ b/source/array-element.d.ts @@ -0,0 +1,28 @@ +/** +Extracts the element type of an array or union of arrays. + +Returns `never` if T is not an array. + +It creates a type-safe way to access the element type of `unknown` type. + +@example +``` +import type {ArrayElement} from 'type-fest'; + +declare const getMostCommonElement: (array: T[]) => ArrayElement; + +getMostCommonElement([1, 2, 3]); +//=> 1 | 2 | 3 + +getMostCommonElement(['foo', 'bar', 'baz'] as const); +//=> 'foo' | 'bar' | 'baz' +``` + +@see {@link ArrayValues} for when you know that the input is an array. + +@category Array +*/ +export type ArrayElement = + ArrayType extends ReadonlyArray + ? ElementType + : never; diff --git a/source/exact.d.ts b/source/exact.d.ts index a6c5686b4..2e1203e20 100644 --- a/source/exact.d.ts +++ b/source/exact.d.ts @@ -1,4 +1,5 @@ -import type {ArrayElement, ObjectValue} from './internal'; +import type {ObjectValue} from './internal'; +import type {ArrayElement} from './array-element'; import type {IsEqual} from './is-equal'; import type {KeysOfUnion} from './keys-of-union'; import type {IsUnknown} from './is-unknown'; diff --git a/source/internal.d.ts b/source/internal.d.ts index f98dfa7a5..e35ee4a5a 100644 --- a/source/internal.d.ts +++ b/source/internal.d.ts @@ -277,15 +277,6 @@ Extracts the type of an array or tuple minus the first element. */ export type ArrayTail = TArray extends readonly [unknown, ...infer TTail] ? TTail : []; -/** -Extract the element of an array that also works for array union. - -Returns `never` if T is not an array. - -It creates a type-safe way to access the element type of `unknown` type. -*/ -export type ArrayElement = T extends readonly unknown[] ? T[0] : never; - /** Extract the object field type if T is an object and K is a key of T, return `never` otherwise. diff --git a/test-d/array-element.ts b/test-d/array-element.ts new file mode 100644 index 000000000..9f967f2cc --- /dev/null +++ b/test-d/array-element.ts @@ -0,0 +1,14 @@ +import {expectType} from 'tsd'; +import type {ArrayElement} from '../index'; + +declare const getArrayElement: (array: T) => ArrayElement; + +expectType(getArrayElement(['a', 'b', 'c'])); +expectType<'a' | 'b' | 'c'>(getArrayElement(['a', 'b', 'c'] as const)); +expectType(getArrayElement([1, 2, 3])); +expectType(getArrayElement(['a', 1])); + +declare const notArray: ArrayElement; + +expectType(getArrayElement([])); +expectType(notArray);