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

Improve pattern matching by inferring results of operations #50112

Closed
4 of 5 tasks
erikologic opened this issue Jul 31, 2022 · 3 comments
Closed
4 of 5 tasks

Improve pattern matching by inferring results of operations #50112

erikologic opened this issue Jul 31, 2022 · 3 comments
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds

Comments

@erikologic
Copy link

Suggestion

It would be amazing for the compiler to be able to infer the result of expressions e.g.:

const twenty: 20 = 10 + 10;
// TS2322: Type 'number' is not assignable to type '20'.

const start: "start" = "start";
const startend: "startend" = start + "end";
// TS2322: Type 'string' is not assignable to type '"startend"'.

🔍 Search Terms

pattern matching, infer result

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code --> I think so - not sure
  • 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

It would be great for tsc to be able to infer the result of primitive operations and cast them to a const e.g.:

const twenty: 20 = 10 + 10;

const start: "start" = "start";
const startend: "startend" = start + "end";

📃 Motivating Example

Why?
To unleash us to do something like:

// <--- INTERESTING BOILERPLATE
type PrependNextNum<A extends Array<unknown>> = A['length'] extends infer T ? ((t: T, ...a: A) => void) extends ((...x: infer X) => void) ? X : never : never;
type EnumerateInternal<A extends Array<unknown>, N extends number> = { 0: A, 1: EnumerateInternal<PrependNextNum<A>, N> }[N extends A['length'] ? 0 : 1];
export type Enumerate<N extends number> = EnumerateInternal<[], N> extends (infer E)[] ? E : never;
export type Range<FROM extends number, TO extends number> = Exclude<Enumerate<TO>, Enumerate<FROM>>;
// --->

const el: Range<1,41> = 10;
const sum: Range<1,41> = el + el;
// TS2322: Type 'number' is not assignable to type '1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40'.

or

// <--- MORE INTERESTING BOILERPLATE
type Length<T extends any[]> =
  T extends { length: infer L } ? L : never;
type BuildTuple<L extends number, T extends any[] = []> =
  T extends { length: L } ? T : BuildTuple<L, [...T, any]>;
type Add<A extends number, B extends number> =
  Length<[...BuildTuple<A>, ...BuildTuple<B>]>;
// --->


const five: Add<3, 2> = 5;
const fiveB: Add<3, 2> = 3 + 2;
// TS2322: Type 'number' is not assignable to type '5'.

Why would this be important?
IMO such a powerful compiler could greatly help the developer experience and the reduce the number of bugs.
I'm a TDD practitioner and I greatly enjoy the feedback loop provided by this practice, but static compiler issues are by far most the best feedback we can get.
I'm quite convinced that introducing this behaviour would make us code way faster.

@whzx5byb
Copy link

Duplicate of 26382

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds labels Aug 3, 2022
@RyanCavanaugh
Copy link
Member

For strings, this already works

const startend: "startend" = `${start}end`;

For numbers, I don't see what's being gained from the type annotation along with the computation. For anything but tautological constructions, there's combinatorial complexity concerns that would outweigh any potential gains.

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Too Complex" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds
Projects
None yet
Development

No branches or pull requests

4 participants