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

Allow as precompiled type cast for type inference #39385

Closed
5 tasks done
vaderkos opened this issue Jul 2, 2020 · 2 comments
Closed
5 tasks done

Allow as precompiled type cast for type inference #39385

vaderkos opened this issue Jul 2, 2020 · 2 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@vaderkos
Copy link

vaderkos commented Jul 2, 2020

Search Terms

runtime const infer inference compile pre dynamic type as

Suggestion

Let known variable types be precompiled to infer types using special cast as precompiled
It would be very helpful in type inference of dynamic code that is generated in runtime but has all types known statically

Example

Now type may be inferred for some variables that have very basic types

const arr1 = [1, 2, 3] // => type is **number[]**
const arr2 = [1, 2, 3] as const // => type is **[1, 2, 3]**
const str1 = 'hello' // => type is **string**
const str2 = 'hello' as const // => type is **'hello'**

But what if we do not want to write types for something that is generated from everything known before compilation

const arr1 = 'A, B, C'.split(',').map(str => string.trim()) // type is **'string[]'**
const arr2 = 'A, B, C'.split(',').map(str => string.trim()) as const // => **now it's Error**
const arr3 = 'A,B,C'.split(',').map(str => string.trim()) as precompiled // => **type is ['A', 'B', 'C']**

Also same feature can be used inside function so proper type inference may be used

That would allow route params type infer

const getPathParamsGetter = (routePattern) => {
  const indexes = routePattern
    .split('/')
    .map(r => r.trim())
    .filter(r => r.length)
    .reduce((acc, part, index) => {
      if (part.startsWith(':')) {
        acc[index] = part.slice(1)
      }
      return acc
    }, {}) as precomiled

  return (path: string) => path
    .split('/')
    .map(r => r.trim())
    .filter(r => r.length)
    .reduce((acc, param, index) => {
      if (indexes.hasOwnProperty(index)) {
        acc[indexes[index]] = param
      }

      return acc
    }, {})
}

// Under the hood we have
// So here the code is executed and then as const is applied
req.params = getPathParamsGetter('/:model/:id')(path) as precompiled

app.get('/:model/:id', function (req, res) {
  const { params } = req /* So here we have params type { model: string, id: string } */
  res.json(params);
});

It only should work when all variables for pre-compilation are known and do not emit any runtime code, only static type checking but with some dynamic features.

Overall feature sound like, run the code if everything is statically known and than cast the result with as const

  • 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, etc.)
  • This feature would agree with the rest of [TypeScript's Design Goals]
@vaderkos vaderkos changed the title Allow pre-compilation for type inference Allow as precompiled type cast for type inference Jul 2, 2020
@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript labels Jul 7, 2020
@RyanCavanaugh
Copy link
Member

Executing user code during compilation time is the first step toward madness; we don't implement features like this and don't intend to.

@jedwards1211
Copy link

jedwards1211 commented May 3, 2024

@RyanCavanaugh how I wish you could be in the trenches with us working on apps where you would benefit from being able to fully type check API boundaries;

experiencing the awkwardness of maintaining codegen tools that keep TS type defs in sync with things like GraphQL, JSON schemas, etc;

accidentally OOMing the compiler when you try to make fancy type magic for computing the exact response type for a REST route from Zod schemas, taking into account up to 4 levels of associated entity inclusion in the request; all because your boss hopes that can be accomplished, and you agree it would be awesome if possible --

only then would you truly understand how desirable this is. We are already deep within the madness. The madness is trying to execute ever-more-complex TypeScript type logic during compilation without exceeding its limits. For us, having a more powerful, flexible form of computation we can perform during compilation feels like the only way out of the madness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants