Skip to content

Allow access to labels in array types and parameter names in functionsΒ #55736

Closed

Description

πŸ” Search Terms

array label name typeof labelof

βœ… Viability Checklist

  • 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 our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

⭐ Suggestion

type MyArray: [one: number, two: boolean, three: string]
type ArrayType = TypeMap<MyArray>

/*
  The above results in a type of:
  [
    { one: number },
    { two: boolean },
    { three: string }
  ]
*/

Similarly:

function myFunc(one: number, two?: boolean, three?: string, ...more: any[]) {}
type FunctionSignature = TypeMap<typeof myFunc>
/*
  The above results in a type of:
  [
    { one: number },
    { two?: boolean },
    { three?: string }
    { more?: any[] }
  ]

  Or maybe it has to be...
  [
    { one: number },
    { two?: boolean },
    { three?: string }
    ...Array<{ more?: any }>
  ]
  
  Not sure how spreads would be mapped exactly...
*/

On its own, the above type signature doesn't do much. But using other advanced type generics, you can get keys of functions (or labels of arrays), the optionality of values, the combined types, etc.

πŸ“ƒ Motivating Example

Within the comments of this issue, describing the array label idea (which was implemented, there were a few questions about retrieving said labels.

I have a use case for wanting access to the labels as keys, specifically for integration with Typia, in which function signatures could be mapped as named arguments in abstracted function calls. (That is, a runtime check to see if the arguments I wish to pass into the function matches the function signature, in an environment where TypeScript is not available to the downstream function for a compile-time check.)

πŸ’» Use Cases

  1. What do you want to use this for?
    Emitting runtime labels of functions.

  2. What shortcomings exist with current approaches?
    There are no current approaches to do this, as far as I know. Array labels and function parameters are hidden from the type system

  3. What workarounds are you using in the meantime?
    The only workaround I can think of is to explicitly and verbosely duplicate all the label names in a function in an external array?

Activity

  1. matthew-dean commented on Sep 13, 2023

    @matthew-dean
    Author

    Oh, interestingly, you could assemble this with the inverse structure:

    type FunctionSignature = [
      { one: number },
      { two?: boolean },
      { three?: string },
      ...Array<{ rest: any }>
    ]
    
    type Params<T> = T extends any[]
      ? {
        [K in keyof T]: T[K][keyof T[K]]
      }
      : never
    
    function myFunc(...args: Params<FunctionSignature>) {
    }

    Maybe that's good enough? πŸ€”

  2. RyanCavanaugh commented on Sep 13, 2023

    @RyanCavanaugh
    Member

    It's intentional that this isn't possible, since two labelled types with the same types but different labels are treated interchangeably. The labels are really, really, really just supposed to be there in the same way that a comment or parameter name is.

  3. matthew-dean commented on Sep 13, 2023

    @matthew-dean
    Author

    Ryan Cavanaugh (@RyanCavanaugh) Okay thanks for the feedback.

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