Skip to content

Handle Type parameter 'T' has a circular default. scenario better #52492

Closed

Description

@jpike88

Suggestion

I've done a lot of research about what I want, and nothing out there seems to reference it. So either what I want is very niche or not possible yet.

I have the following type defined:

type TableUpdateFn<T = any> = {
	apiCall: (
		query: Query,
		progressCallback?: (progressType, loaded, total) => void,
		isCancellable?: boolean
	) => Promise<{ rows: T[]; count: number }>;
	transformRows?: (
		rows: T[],
		customTableComponent: CustomTableComponent
	) => Promise<void>;
	selected?: (sourceObj: T) => boolean;
	warning?: (sourceObj: T) => boolean;
};

The most important thing about this type is the type of the rows property (a single item, not the array type applied to it) returned by the apiCall promise. This type should determine how other functions are on the rest of the type.

Using generics seems like the most reasonable way to handle this, but unfortunately I'm stuck with either manually specifying the generic each time I use this type (which defeats the purpose of relying on apiCall for the type), or just defaulting to any.

What I would like to be able to do is something like this, which means the whole object matching this type will inherit the type of rows[0]:

type TableUpdateFn<
	T = Awaited<ReturnType<this['apiCall']>>['rows'][0]
> = {
	apiCall: (
		query: Query,
		progressCallback?: (progressType, loaded, total) => void,
		isCancellable?: boolean
	) => Promise<{ rows: T[]; count: number }>;
	transformRows?: (
		rows: T[],
		customTableComponent: CustomTableComponent
	) => Promise<void>;
	selected?: (sourceObj: T) => boolean;
	warning?: (sourceObj: T) => boolean;
};

🔍 Search Terms

interface self-reference recursion

Activity

  1. jpike88 commented on Jan 30, 2023

    @jpike88
    Author

    Another notes:

    Even though typescript complains about the second example in my post above, my codebase lit up with some errors which actually helped me.

    The below code snippet for example was invalid but got flagged, which again is a good thing:

    const updateFn: TableUpdateFn<X> = {
         apiCall:... // { rows: Y[], count: number},
         selected: (someVar) =>...// do something with someVar, which would be of type X,
    ...
    }
    

    Only problem is that the selected method in the above method errored because someVar became type unknown instead of the type I wanted (type Y)

  2. typescript-bot commented on Feb 2, 2023

    @typescript-bot
    Contributor

    This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow or the TypeScript Discord community.

  3. locked as resolved and limited conversation to collaborators on Oct 22, 2025
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

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions