Skip to content

Allow as precompiled type cast for type inference #39385

Description

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]

Activity

  1. changed the title [-]Allow pre-compilation for type inference[/-] [+]Allow as precompiled type cast for type inference[/+] on Jul 2, 2020
  2. RyanCavanaugh commented on Jul 7, 2020

    @RyanCavanaugh
    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.

  3. jedwards1211 commented on May 3, 2024

    @jedwards1211

    Ryan Cavanaugh (@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

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions