Skip to content

Generic type parameter not inferring properly #58651

Not planned
@dpizzo-at-aops

Description

@dpizzo-at-aops

🔎 Search Terms

"object key order matters"
"infer first occurrence"

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics
  • This changed (for the better) between versions 4.6.4 and 4.7.4 (more info below)

⏯ Playground Link

playground

💻 Code

export type Foo = {
	foo: string;
};

export type Constraint<F extends Foo> = {
	part1(): F;
	part2(p1: F): void;
};

export type Constraint2<F extends Foo> = {
	part1(): F;
	part2(p1: NoInfer<F>): void;
};

// Replacing `Constraint` with `Constraint2` has no difference
export const inferStuff = <F extends Foo>(thing: Constraint<F>) => {
	return thing;
};

// This correctly infers the type parameter to have both the `foo` and `bar` keys ...
const correct = inferStuff({
	part1() {
		return {
			foo: "bar",
			bar: "baz",
		};
	},
	part2(p1) {},
});

// ... while this does not ...
const incorrect = inferStuff({
	part2(p1) {},
	part1() {
		return {
			foo: "bar",
			bar: "baz",
		};
	},
})

// ... but this does again ?
const whatIsHappening = inferStuff({
	part2() {},
	part1() {
		return {
			foo: "bar",
			bar: "baz",
		};
	},
})

🙁 Actual behavior

When part1 appears before part2, or when the parameter to part2 is omitted, then the type parameter is properly inferred. When part2 appears before part1 with a parameter, then the type parameter is inferred incorrectly, even when using Constraint2 which has NoInfer on that parameter's type.

In 4.6.4 and below, correct has the same type as incorrect (the order of the keys in the object didn't matter, but inferred less specifically).

🙂 Expected behavior

All three usages should be equivalent to each other, and in particular, should infer as Constraint<{ foo: string; bar: string; }>.

Additional information about the issue

Here's another example, that shows relatedly incorrect behavior: playground

Activity

Andarist

Andarist commented on May 24, 2024

@Andarist
Contributor

This is a known~ limitation of the intra-expression site inference that was introduced in TS 4.7 (here). For it to work the producer has to come before the consumer.

RyanCavanaugh

RyanCavanaugh commented on Jun 7, 2024

@RyanCavanaugh
Member

See #47599

typescript-bot

typescript-bot commented on Jun 10, 2024

@typescript-bot
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

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

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @RyanCavanaugh@Andarist@typescript-bot@dpizzo-at-aops

        Issue actions

          Generic type parameter not inferring properly · Issue #58651 · microsoft/TypeScript