Skip to content
This repository has been archived by the owner on Oct 8, 2024. It is now read-only.

TypeScript concerns #116

Closed
Jack-Works opened this issue Jul 26, 2020 · 4 comments
Closed

TypeScript concerns #116

Jack-Works opened this issue Jul 26, 2020 · 4 comments
Labels
invalid This doesn't seem right

Comments

@Jack-Works
Copy link
Member

This is actually not an iterator helper issue, hope the TypeScript team can see this (maybe CC @DanielRosenwasser or @rbuckton ?)

Now the Iterator helpers are adding methods to %IteratorPrototype%.

In TypeScript, it is the global interface Iterator

interface Iterator<T, TReturn = any, TNext = undefined> {
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return?(value?: TReturn): IteratorResult<T, TReturn>;
    throw?(e?: any): IteratorResult<T, TReturn>;
}

If the typing of methods are added to the Iterator interface directly, for example,

interface Iterator<T, TReturn = any, TNext = undefined> {
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return?(value?: TReturn): IteratorResult<T, TReturn>;
    throw?(e?: any): IteratorResult<T, TReturn>;
    map<Q>(mapper: (t: T) => Q): Iterator<Q, TReturn, TNext>
}

it will make more runtime error because the developer will trust the typing system and forgot to use Iterator.from to convert manually written Iterators to inherit from %IteratorPrototype%.

For example, a not maintaining package is providing manually written iterators and export the type definition follows:

export function iter_number(from: number, to: number): Iterator<number>

And the developer with newer typescript that has Iterator Helper methods on the Iterator interface will get the code completion of map

image

But actually this is wrong.

iter_number(0, 5).map(x => x + 1) // !!!!! Runtime Error but no type Error!
Iterator.from(iter_number(0, 5)).map(x => x + 1) // OK

My suggestion is to add a new builtin interface IteratorPrototypeIterator<...> extends Iterator<...> and add Iterator Helpers on it. Then, all built-in methods and the Generator interface extend IteratorPrototypeIterator.
In this way, manually implementing Iterator<> interface will not be considered to have iterator helper methods by the type system.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jul 27, 2020

This is really a similar concern as the distinction between PromiseLike and Promise, right? PromiseLike can be used by lots of constructs in the language because it really describes a structural protocol, but Promise is used more to describe a concrete instance, and has things like finally() built into it.

If that's the case, I'd say that in an ideal world, most existing instances of Iterator would be replaced with something like IteratorLike. I guess you've suggested the breaking-change-free route of declaring an IteratorPrototypeIterator instead. I'm not big on the name, but it is an option.

@ljharb
Copy link
Member

ljharb commented Jul 27, 2020

IteratorForReal

@ljharb
Copy link
Member

ljharb commented Jul 27, 2020

@DanielRosenwasser this does suggest that TS should probably try to ensure its types for protocols (like "iterable", "thenable", "toString-able", etc) all end in "Like", or some other convention?

@devsnek devsnek added the invalid This doesn't seem right label Jul 27, 2020
@bakkot
Copy link
Collaborator

bakkot commented Jul 6, 2022

TypeScript will need to resolve this internally, but we're definitely going to stick with Iterator here, so I don't think there's further action items for this proposal.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

5 participants