Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic type parameter not inferring properly #58651

Closed
dpizzo-at-aops opened this issue May 24, 2024 · 3 comments
Closed

Generic type parameter not inferring properly #58651

dpizzo-at-aops opened this issue May 24, 2024 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@dpizzo-at-aops
Copy link

dpizzo-at-aops commented May 24, 2024

🔎 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

@Andarist
Copy link
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
Copy link
Member

See #47599

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jun 7, 2024
@typescript-bot
Copy link
Collaborator

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

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants