Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose ArrayElement type #914

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

tommy-mitchell
Copy link
Contributor

@tommy-mitchell tommy-mitchell commented Jul 14, 2024

Closes #118
Related: #676. (maybe closes?)

Exposes internal ArrayElement type:

Extracts the element type of an array or union of arrays.

import type {ArrayElement} from 'type-fest';

declare const getMostCommonElement: <T>(array: T[]) => ArrayElement<typeof array>;

getMostCommonElement([1, 2, 3]);
//=> 1 | 2 | 3

getMostCommonElement(['foo', 'bar', 'baz'] as const);
//=> 'foo' | 'bar' | 'baz'

Comment on lines +25 to +28
export type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends ReadonlyArray<infer ElementType>
? ElementType
: never;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this works @strongpauly

Should this be more?:

type ArrayElement<ArrayType extends readonly unknown[]> = 
  ArrayType extends readonly (infer ElementType)[] ? ElementType : never;

Copy paste from stackoverflow.com/questions/41253310/typescript-retrieve-element-type-information-from-array-type

// #906 (comment)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, as long as it returns a union of the types of the array elements, its fit for purpose, IMO.

@sindresorhus
Copy link
Owner

Isn't this type already covered by https://github.com/sindresorhus/type-fest/blob/main/source/iterable-element.d.ts ?

@tommy-mitchell
Copy link
Contributor Author

Isn't this type already covered by main/source/iterable-element.d.ts ?

Hm, I'd assume so, but the tests for Exact fail if swapped to use IterableElement:

image

@bombillazo
Copy link

Any update here?

@fregante
Copy link
Collaborator

fregante commented Aug 22, 2024

Is it really worth to import and use a custom type instead of just using a literal type offered by TypeScript?

- array[number]
+ ArrayElement<array>

The examples and tests don’t show why this would be beneficial.

@bombillazo
Copy link

Is it really worth to import and use a custom type instead of just using a literal type offered by TypeScript?

- array[number]
+ ArrayElement<array>

It's more of a syntactic and aesthetic improvement than a functional one. I do think it is a bit more verbose, but the type offered by TS can be hard to read/interpret at first glance:

type MyType = MyComplexType['property_1'][number]['subprop_1'] | null
// vs
type MyType = ArrayElement<MyComplexType['property_1']>['subprop_1'] | null

@fregante
Copy link
Collaborator

fregante commented Aug 29, 2024

In your example it does not look like an advantage, it's hard to follow and does not match the order of the JS code.

              0             1            2        3 
              complexObject .property_1  [0]      .subprop_1

              0             1            2        3
type MyType = MyComplexType['property_1'][number]['subprop_1'] | null
// vs

              2           0             1              3
type MyType = ArrayElement<MyComplexType['property_1']>['subprop_1'] | null

I agree that ArrayElement<array> is more clear than array[number] to the untrained eye, but introducing this utility means that you'll inevitably end up with both on the codebase anyway, because it's not standard and people generally don't expect to use utilities to replace basic syntax.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: ArrayItem
5 participants