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

Support Array.prototype.at #45512

Closed
bpasero opened this issue Aug 19, 2021 · 25 comments · Fixed by #46291
Closed

Support Array.prototype.at #45512

bpasero opened this issue Aug 19, 2021 · 25 comments · Fixed by #46291
Labels
Bug A bug in TypeScript Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript ES Next New featurers for ECMAScript (a.k.a. ESNext) Help Wanted You can do this

Comments

@bpasero
Copy link
Member

bpasero commented Aug 19, 2021

There is a new method being added for Array: at

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at

I think typing this in a way that undefined is returned would allow a gradual adoption of the noUncheckedIndexedAccess rule:

at(index: number): T | undefined;
@MartinJohns
Copy link
Contributor

MartinJohns commented Aug 19, 2021

I think typing this in a way that undefined is returned would allow a gradual adoption of the noUncheckedIndexedAccess rule:

I don't see how this is related to noUncheckedIndexedAccess. The function returns an explicit undefined if the index does not exist.

Also, please note that there is an issue template for library changes: lib_change.md

@bpasero
Copy link
Member Author

bpasero commented Aug 19, 2021

I don't see how this is related to noUncheckedIndexedAccess.

Being in a codebase that would produce hundreds of compile errors when noUncheckedIndexedAccess is enabled, adopting Array.at would allow to gradually adopt this to the point where noUncheckedIndexedAccess could then be enabled by default.

I notice #36554 exists, should I merge my issue into there?

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Help Wanted You can do this labels Aug 19, 2021
@DanielRosenwasser DanielRosenwasser added the ES Next New featurers for ECMAScript (a.k.a. ESNext) label Aug 20, 2021
@SimonSchick
Copy link

You can always just add ! null assertions to your array indexing, and gradually remove it, at shouldn't be used as a migration strategy imo.

@bpasero
Copy link
Member Author

bpasero commented Aug 20, 2021

👎 For me, using ! is like using any and I stay away from it unless there is really no other way.

@FelipeSharkao
Copy link

The biggest thing of Array.prototype.at is the possibility to use negative indexes. array.at(-1) is way clearer than array[array.length - 1].

@orta
Copy link
Contributor

orta commented Sep 2, 2021

We chatted in the design meeting about this #45551, and agreed with @bpasero that it's a good call (and we debated techniques for typing the minus numbers but don't have an instant answer yet)

Also linking to #44656 which this should probably be a part of

@Ethan-G
Copy link

Ethan-G commented Sep 24, 2021

For impacts: I went to use .at() today only to discover it's not supported yet.

@jonlepage
Copy link

ho i lost so many time to try understand !
image

So It not yet added ! ?

@MartinJohns
Copy link
Contributor

Also linking to #44656 which this should probably be a part of

@orta You probably mean #44571.

@unicornware
Copy link

unicornware commented Oct 25, 2021

@Ethan-G not sure if you found a workaround yet, but i ended up adding a custom .d.ts file (i also tried upgrading to typescript@4.5.0-beta, but found that Array.prototype.at wasn't supported in that version either):

// typings/lib.esnext.array.d.ts

/** @template T - Array item type */
interface Array<T> {
  /**
   * Takes an integer value and returns the item at that index, allowing for
   * positive and negative integers. Negative integers count back from the last
   * item in the array.
   *
   * @param {number} index - Position of the array element to be returned
   * @return {T | undefined} Element in the array matching the given index.
   * Returns `undefined` if the given index can not be found
   */
  at(index: number): T | undefined
}

/** @template T - Array item type */
interface ReadonlyArray<T> {
  at: Array<T>['at']
}

docs pulled from MDN.

@PabloLION
Copy link

I'm with typescript@4.5.3 yet still having the same problem as @djmisterjon did.
In the playground it shows the same. How should I configure TS to suppress the error?

@PabloLION
Copy link

It seems I would have to wait until es2022 lib comes out?

@jonlepage
Copy link

it added in 2022 lib
image

@PabloLION
Copy link

I can't get ES2022 lib in my TSconfig with 4.5.3.. I'll wait for 4.6

@jonlepage
Copy link

I can't get ES2022 lib in my TSconfig with 4.5.3.. I'll wait for 4.6

ho you may true, i using 4.6-dev in my workspace
image

@hochan222
Copy link

Thanks to those who raised the issue in the first place!

@PabloLION
Copy link

As for now, this functionality is supported by typescript@4.5.4, while setting the tsconfig.module to es2022.

@RebeccaStevens
Copy link

Would it be possible to change the return type of at for tuples?
For example make it so that ([1, 2, 3] as const).at(1) will be 2 rather than number | undefined?

Or would this be too difficult considering that we'd need to take into account how negative indexes work?

@jonlepage
Copy link

jonlepage commented Jan 29, 2022

hum yes , maybe they will need change the way how the generic share value.
Maybe try open a new post
Here a hack solution where is work !
edit: not handle negative index

interface ReadonlyArray<T> {
    /**
     * Returns the item located at the specified index.
     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.
     */
    at<U extends number>(index: U): this[U] | undefined;
}

@PabloLION
Copy link

I agree with @djmisterjon 's idea on new post.
But here's the code I used. const a = (([1, 2, 3] as const).at(1 as const))!
BTW @djmisterjon I find your "hack solucion" doesn't work. maybe you used a T and a U?

@PabloLION
Copy link

The ! I used was for the at() method cannot check if the element exists, so a | undefined is always deduced. I remembered that this problem is reported.

@jonlepage
Copy link

i dont know what to say, worked on my side with the hack

image
And if you remove as const it become number
image

So for me its should natively support this without manual hack.

@PabloLION
Copy link

I think it's working correctly. TS deduces that the type of [1,2,3] is number[], like [] as never[]. What do you suggest here..?

@MartinJohns
Copy link
Contributor

@djmisterjon That's not a hack, that's the expected and desired behaviour.

@jonlepage
Copy link

...heum ,hi, i think you don't understand the meaning of the word hack in this context.
Hack mean bidouillage and not hacking.
Hack your code or hack this code can mean add, edit or modify
Modify (hack) the native code provided by default to test a new behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript ES Next New featurers for ECMAScript (a.k.a. ESNext) Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.