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 — Support higher order inferences for constructor functions by ahejlsberg · Pull Request #31116 · microsoft/TypeScript

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Apr 25, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

This PR expands on #30215 to support higher order inferences for constructor functions and to permit function type arguments to higher order composition functions to have other members in addition to their single call signature.

Some examples:

declare class Point {
    constructor(x: number, y: number);
    readonly x: number;
    readonly y: number;
}

declare class Bag<T> {
    constructor(...args: T[]);
    contains(value: T): boolean;
    static foo: string;
}

function asFunction<A extends any[], B>(cf: new (...args: A) => B) {
    return (...args: A) => new cf(...args);
}

const newPoint = asFunction(Point);  // (x: number, y: number) => Point
const newBag = asFunction(Bag);      // <T>(...args: T[]) => Bag<T>
const p1 = new Point(10, 20);        // Point
const p2 = newPoint(10, 20);         // Point
const bag1 = new Bag(1, 2, 3);       // Bag<number>
const bag2 = newBag('a', 'b', 'c');  // Bag<string>

declare class Component<P> {
    props: P;
    constructor(props: P);
}

type ComponentClass<P> = new (props: P) => Component<P>;

declare function myHoc<P>(C: ComponentClass<P>): ComponentClass<P>;

type GenericProps<T> = { foo: number, stuff: T };

declare class GenericComponent<T> extends Component<GenericProps<T>> {}

// const GenericComponent2: new <T>(props: GenericProps<T>) => Component<GenericProps<T>>
const GenericComponent2 = myHoc(GenericComponent);

The rules for determining when higher order inferences occur are revised as follows. Given a generic function f of type <…>(…, x: P, …) => R, and an argument expression a of a generic function type A, in a call expression f(…, a, …) the type parameters of A are propagated onto the inferred result type of the function call if:

  • P is a function type with no type arguments, a single call or construct signature, and no other members, and
  • R is a function type with no type arguments, a single call or construct signature, and no other members, and
  • A is function type with type arguments and a single call or construct signature that matches P (note that A is permitted to have other members), and
  • in the left-to-right processing of the function call arguments, no inferences have been made for any of the type parameters referenced in P.

Fixes #30650.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Igorbek, jovdb, hugoferreira, c69, aminpaks, fvilante, SpencerPark, fwh1990, FabianLauer, asciphx, and 10 more reacted with thumbs up emoji fvilante reacted with laugh emoji dragomirtitian, bradleyayers, earthlyreason, ulrichb, hugoferreira, fvilante, leoyli, unao, and jkillian reacted with hooray emoji ulrichb, hugoferreira, OctoD, aminpaks, fvilante, unao, and jkillian reacted with heart emoji fvilante, jkillian, and Znack reacted with rocket emoji
All reactions
  • 👍 20 reactions
  • 😄 1 reaction
  • 🎉 9 reactions
  • ❤️ 7 reactions
  • 🚀 3 reactions
Anders Hejlsberg (ahejlsberg) added 2 commits April 25, 2019 09:58
@ahejlsberg
Support higher order inferences for constructor functions
4384c90
@ahejlsberg
Accept new baselines
fcd6f52
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Apr 25, 2019

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) test this

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Apr 25, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at fcd6f52. You can monitor the build here. It should now contribute to this PR's status checks.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Apr 25, 2019

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) run dt

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Apr 25, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at fcd6f52. You can monitor the build here. It should now contribute to this PR's status checks.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg
Only defer pure functions and pure constructor functions during infer…
4fe59dc
…ence
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Apr 25, 2019

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) run dt

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Apr 25, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 4fe59dc. You can monitor the build here. It should now contribute to this PR's status checks.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@weswigham

Wesley Wigham (weswigham) commented Apr 25, 2019

Copy link
Copy Markdown
Member

The react-test-renderer failure is in master, so I think DT is clean.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Anders Hejlsberg (ahejlsberg) added 3 commits April 25, 2019 13:46
@ahejlsberg
Accept new baselines
50f5e16
@ahejlsberg
Only defer function type inference when contextual type is function type
be88d53
@ahejlsberg
Accept new baselines
3e79e8d
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Apr 26, 2019

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) run dt

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Apr 26, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 3e79e8d. You can monitor the build here. It should now contribute to this PR's status checks.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) mentioned this pull request Apr 26, 2019
Design Meeting Notes, 4/26/2019 #31132
Closed
Anders Hejlsberg (ahejlsberg) added 2 commits April 27, 2019 07:51
@ahejlsberg
Add tests
53cbea7
@ahejlsberg
Accept new baselines
4051d73
@ahejlsberg Anders Hejlsberg (ahejlsberg) mentioned this pull request Apr 27, 2019
Higher order type inference from generic React component #30650
Closed
@ahejlsberg
Anders Hejlsberg (ahejlsberg) requested review from Daniel Rosenwasser (DanielRosenwasser), Ryan Cavanaugh (RyanCavanaugh) and Wesley Wigham (weswigham) April 30, 2019 13:27
RyanCavanaugh
Ryan Cavanaugh (RyanCavanaugh) approved these changes Apr 30, 2019
View reviewed changes
@ahejlsberg
Anders Hejlsberg (ahejlsberg) merged commit 9005449 into master Apr 30, 2019
@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the higherOrderConstructorTypes branch April 30, 2019 15:42
@ajafff Klaus Meinhardt (ajafff) mentioned this pull request Apr 30, 2019
no-uninferred-type-parameter: handle higher order constructor inference fimbullinter/wotan#605
Closed
@guykr

Guy Kremnitzer (guykr) commented Jun 18, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Hi Ryan Cavanaugh (@RyanCavanaugh) Anders Hejlsberg (@ahejlsberg),
when trying to use this new mechanism with React's ComponentClass I noticed this does not actually work, the inferred type is actually: const GenericComponent2: ComponentClass<GenericProps<unknown>> not const GenericComponent2: new <T>(props: GenericProps<T>) => Component<GenericProps<T>>

Please find below an adapted example from the one in this PR:

declare class Point {
  constructor(x: number, y: number)
  readonly x: number
  readonly y: number
}

declare class Bag<T> {
  constructor(...args: T[])
  contains(value: T): boolean
  static foo: string
}

function asFunction<A extends any[], B>(cf: new (...args: A) => B) {
  return (...args: A) => new cf(...args)
}

const newPoint = asFunction(Point) // (x: number, y: number) => Point
const newBag = asFunction(Bag) // <T>(...args: T[]) => Bag<T>
const p1 = new Point(10, 20) // Point
const p2 = newPoint(10, 20) // Point
const bag1 = new Bag(1, 2, 3) // Bag<number>
const bag2 = newBag('a', 'b', 'c') // Bag<string>

declare class Component<P> {
  props: P
  constructor(props: P)
}

interface ComponentClass<P> {
  new (props: P): Component<P>
  thisWillBreakGenericInference?: boolean // <--- this is breaking the type inference
}

declare function myHoc<P>(C: ComponentClass<P>): ComponentClass<P>

type GenericProps<T> = { foo: number; stuff: T }

declare class GenericComponent<T> extends Component<GenericProps<T>> {}

// Should be:
// const GenericComponent2: new <T>(props: GenericProps<T>) => Component<GenericProps<T>>
// Actually: 
// const GenericComponent2: ComponentClass<GenericProps<unknown>>

const GenericComponent2 = myHoc(GenericComponent)

Link to playground:
The change I made is in line 31.

The issue here is that React's ComponentClass interface has a few optional members defined.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Jun 18, 2019

Copy link
Copy Markdown
Member Author

@guykr-stratoscale That's a known limitation. See discussion in #30650 (comment).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@RichardForrester

Jeanette Vang (RichardForrester) commented Jul 21, 2019

Copy link
Copy Markdown

It's really encouraging that TS is getting some more support for functional programmers. Keep up the good work!

Small critique on the announcement docs. The function you guys are showing off as compose is backwards and without currying is not really a realistic implementation.

function compose<T, U, V>(
    f: (x: T) => U, g: (y: U) => V): (x: T) => V {
    
    return x => g(f(x))
}

Based on all of the below resources:

-- Haskell
(.) :: (b -> c) -> (a -> b) -> a -> c
// Sanctuary.js
compose :: Semigroupoid s => s b c -> s a b -> s a c

// fp-ts
export interface Semigroupoid<F> {
  readonly URI: F
  readonly compose: <E, A, B>(ab: HKT2<F, A, B>, la: HKT2<F, E, A>) => HKT2<F, E, B>
}

// Ramda
(b -> c) -> (a -> b) -> a -> c

// Crocks
composeB :: (b -> c) -> (a -> b) -> a -> c

I understand the the announcement docs are just for simple illustration, and it's great. I'm thrilled about the attention to the functional side of javascript. But it would be nice to have simple and correct code for the docs, maybe something like:

type fn1<I, O> = (i: I) => O
type compose = <T extends any, U, V>(f: fn1<U, V>) => (g: fn1<T, U>) => fn1<T, V>
const compose: compose = f => g => a => f (g (a))
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Aug 28, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
2443a92
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Oct 27, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
62a7dde
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 4, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
f0ed311
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 13, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
151ac8c
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 16, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
2885e84
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 22, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
54a2399
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 25, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
0199434
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 26, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
62ac294
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 27, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
e905ffa
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 28, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
1de1cd1
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Nov 29, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
5f1d1af
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Dec 28, 2019
@jablko
Higher order this parameter inference, like microsoft#31116
8b4090b
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 21, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
9e2761f
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 25, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
257c735
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 25, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
9a594db
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Jan 29, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
c0ec24c
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 3, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
d753470
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 3, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
8dd7c4a
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 4, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
d2967d0
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 6, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
d10f6bb
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 9, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
5f119f3
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 10, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
4485ed5
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 11, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
0fa0a83
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 12, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
6de585b
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 12, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
ba0c8f3
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 13, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
edf3ce2
@2A5F Package (2A5F) mentioned this pull request Feb 17, 2020
First class type constructor #35816
Closed
5 tasks done
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 21, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
327dea7
Jack Bates (jablko) added a commit to jablko/TypeScript that referenced this pull request Feb 22, 2020
@jablko
Higher order this parameter inference, like microsoft#31116
4fcf8c7
@LukeAbby LukeAbby mentioned this pull request Apr 30, 2025
Broken inference for generic classes passed to a generic function taking an optional class #61633
Open
@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) RyanCavanaugh approved these changes
@weswigham Wesley Wigham (weswigham) Awaiting requested review from weswigham
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Awaiting requested review from DanielRosenwasser

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Higher order type inference from generic React component

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@ahejlsberg @typescript-bot @weswigham @guykr @RichardForrester @Luxcium @RyanCavanaugh
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.