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

Evaluate mathematical expression of indices when indexing tuples #42693

Open
5 tasks done
stephanemagnenat opened this issue Feb 8, 2021 · 1 comment
Open
5 tasks done
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@stephanemagnenat
Copy link

stephanemagnenat commented Feb 8, 2021

Suggestion

πŸ” Search Terms

tuple bounds, tuple index computing, bound checking removal, noUncheckedIndexedAccess

βœ… Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Currently (version 4.1), Typescript is able to deduce that an array access to a tuple is within bounds if it is indexed by an integer literal union type that fits within the array, e.g.:

type I = 0 | 1 | 2;
function access(i: I, a: [string, string, string]) {
    return a[i];
} // type: string, even with noUncheckedIndexedAccess = true

However, as soon as there is an operation on the indexing variable, even trivial, Typescript falls back to inferring number. Therefore, the following code:

type I = 0 | 1;
function access(i: I, a: [string, string, string]) {
    return a[i + 1];
} // type: string | undefined, when noUncheckedIndexedAccess = true

In principle, Typescript could reason a bit deeper on the set of possible integer values when going through operations, especially for the trivial ones like in my example. If there is a lot of values in the union, it might be computationally expensive, but in that case a conservative bound analysis would already be enough for most uses cases (see #15480).

πŸ“ƒ Motivating Example

The proposed feature would at minimum allow:

type I = 0 | 1;
function access(i: I, a: [string, string, string]) {
    return a[i + 1];
}

and, if possible, use cases such as:

type Vector = [number, number];
type Matrix = [number, number, number, number];
const Range = [0, 1] as const;
function mult(m: Matrix, v: Vector) {
    let ret: Vector = [0, 0];
    for (const i of Range) {
        let acc = 0;
        for (const j of Range) {
            acc += v[j] * m[i * 2 + j];
        }
        ret[i] = acc;
    }
    return ret;
}

and, if Vector and Matrix can be aliases to fixed-size typed arrays (see #18471) in addition to tuple, it would be wonderful.

πŸ’» Use Cases

That feature would be very useful in conjunction with noUncheckedIndexedAccess obviously, but also with a way to statically type the length of TypedArray (see #18471) for use in mathematical and graphics code. But even without typed arrays, it would still be useful in day-to-day code. I'm experimenting in switching our 45 kloc Typescript code base to noUncheckedIndexedAccess = true and that feature would increase type safety in several places.

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Feb 8, 2021
@RyanCavanaugh RyanCavanaugh changed the title Improve bounds reasoning when indexing tuples Evaluate mathematical expression of indices when indexing tuples Feb 8, 2021
@jcalz
Copy link
Contributor

jcalz commented Feb 9, 2021

cross-referencing #15645 and #26382

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants