Skip to content

Apply function generics as part of type definition #40542

Closed

Description

Search Terms

generic typeof functions

Suggestion

The problem is with the code as below:

const id = <T>(val: T) => val
type IdType = typeof id
// type IdType = <T>(val: T) => T

type Ret = ReturnType<typeof id>
// type Ret = unknown

It would be nice to be able to do something like so:

const id = <T>(val: T) => val
type IdType<T> = (typeof id)<T>
// type IdType<T> = (val: T) => T

// Or by extension:
type Ret<T> = ReturnType<(typeof id)<T>>
// type Ret<T> = T

Use Cases

This would be useful to use with the vriad/zod library, to implement different field validators depending on a parameter, like so:

// the dateSchema param could be a schema for an ISO 8601 string or a Date object, or even some custom date-like type
const fooSchema = <T>(dateSchema: z.ZodSchema<T>) => z.object({
  name: z.string(),
  date: dateSchema
})
type Foo<T> = z.infer<ReturnType<(typeof fooSchema)<T>>>
// expected result: type Foo<T> = { name: string, date: T }

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, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Activity

  1. Gozala commented on Jun 9, 2021

    @Gozala

    I am understanding this proposal correctly that IdType here

    const id = <T>(val: T) => val
    type IdType = typeof id
    

    would be type IdType<T> = (val:T) => T as opposed to type IdType = <T>(val:T) => T ? Or is idea here that you you should be able to qualify generic function type like type IdType = <T>(val:T) => T via <T> suffix e.g. type IdNum = IdType<number> // (val:number) => number ?

  2. jmacmahon commented on Jun 29, 2021

    @jmacmahon
    Author

    I meant the latter, so like you say, type IdNum = IdType<number> // (val:number) => number.

    I think the former would be incorrect, because the parameter T is not present when declaring type IdType.

  3. ahejlsberg commented on Jan 27, 2022

    @ahejlsberg
    Member

    This feature is now implemented in #47607.

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

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions