GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Type instantiation for type level generic function · Issue #62524 · microsoft/TypeScript

Type instantiation for type level generic function #62524

New issue
Copy link
New issue
Copy link
Open
Open
Type instantiation for type level generic function#62524
Copy link
Labels
Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript

Description

@mhofman
Mathieu Hofman (mhofman)
opened on Oct 2, 2025
Issue body actions

🔍 Search Terms

type instantiation
type level generic function
generic return type

Related: #40542, #61133 and maybe #52035?

Edit: Just found #55435 and #40179

✅ 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 isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
  • This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

⭐ Suggestion

#47607 added support for instantiation expressions, but those do not apply at the type level. I understand it'd be ambiguous in some cases (#47607 (comment)), but in some cases there really isn't a reasonable workaround.

📃 Motivating Example

I actually have a very similar case to the example provided in #40542

const provideBox = () => {
    const box = <T>(value: T) => ({value});
    return box;
};

type BoxMaker = ReturnType<typeof provideBox>
// type BoxMaker = <T>(value: T) => { value: T; }

type Box1<T> = ReturnType<BoxMaker<T>>;
// Type 'BoxMaker' is not generic.(2315)

const box = undefined as unknown as BoxMaker;

type Box2<T> = ReturnType<typeof box<T>>;
//type Box2<T> = { value: T; }
Compiler Options
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "target": "ES2017",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}

Playground Link: Provided

💻 Use Cases

  1. What do you want to use this for?

In our case we have a more complex provideBox that accept arguments. We also need to rely on type inference for the generic type of the box function and its return value;

  1. What shortcomings exist with current approaches?

I cannot extract and export a generic type for a return value of a generic function if I don't have direct reference to the function.

  1. What workarounds are you using in the meantime?

The only workaround I found is to use a dummy runtime value to apply the type, and use and instantiation expression on that dummy value (see Box2 above)

Activity

  1. RyanCavanaugh commented on Oct 2, 2025

    @RyanCavanaugh
    Ryan Cavanaugh (RyanCavanaugh)
    on Oct 2, 2025
    Member
    More actions

    Duplicate #40179

  2. mhofman commented on Oct 2, 2025

    @mhofman
    Mathieu Hofman (mhofman)
    on Oct 2, 2025
    Author
    More actions

    I'm not sure what I described can always be a duplicate of #40179
    In particular, there may not be runtime arguments to be provided, yet the result can be a generic (requiring explicit generic type on the function call).

  3. Ryan Cavanaugh (RyanCavanaugh)
    added
    SuggestionAn idea for TypeScriptAn idea for TypeScript
    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this feature
    on Oct 2, 2025
  4. I-Enderlord-I commented on Nov 23, 2025

    @I-Enderlord-I
    __Enderlord__ (I-Enderlord-I)
    on Nov 23, 2025
    More actions

    This feature would be immensely useful when constructing types from generic types. I have seen the comment about ambiguity in #47607, but I honestly don't see why that would be a problem. At the time of type checking it is known whether a type identifier is generic or not. And when it is, instantiating a generic function inside it should simply not work. Think of

    type Test<X> = <Y extends X>(x: Y) => Y;

    There is simply no way to pass a concrete type into Y before specifying X as the constraint is not known. So writing

    type A = Test<string>;

    should obviously set X to string and not Y, resolving as

    type A = <Y extends string>(x: Y) => Y;

    and then making it possible to do

    type B = A<'a' | 'b'>;

    to get

    type B = (x: 'a' | 'b') => 'a' | 'b';
  5. I-Enderlord-I commented on Nov 23, 2025

    @I-Enderlord-I
    __Enderlord__ (I-Enderlord-I)
    on Nov 23, 2025
    More actions

    Also issues like #40179 are definitely not duplicates of, but merely included in this, as there the discussion is solely on return types. Having type instantiation would also allow

    // in library
    class Config<T> {
      ...
      get<K extends keyof T & string>(key: K): T[K];
      set<K extends keyof T & string>(key: K, value: SomethingComplicated<T, K>): void;
    }
    
    //in application
    type IConfig {
      a: string;
    }
    const config = new Config<IConfig>();
    function setA(value: Parameters<Config<IConfig>['set']<'a'>>[1]) {
      config.set('a', value);
    }
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 featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.