Skip to content

TypeScript can't infer type of default parameters #59643

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

Open
SukkaW opened this issue Aug 15, 2024 · 2 comments
Open

TypeScript can't infer type of default parameters #59643

SukkaW opened this issue Aug 15, 2024 · 2 comments
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases

Comments

@SukkaW
Copy link

SukkaW commented Aug 15, 2024

🔎 Search Terms

infer default parameters
function wrapper
function factory

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ
    • I tried down to version 4.0.3 (since in the earlier version Generator type is not generic)

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtVNQBEQYsA3EAHgEF4QAPDEVYAZ3jQGtUcB3VANoBdADTwASgD4AFACh4CggC540gHQbYAc1YrqASngBeSfADizElAw4YlLj35ipI2fpUO++APQAqX-AAtjhgnCDA8HAYyDD4vt4A3LKyiEQk5CDSKOjYePC+0lDG8AAMYgBGxQDkVYYA3vLwYHisOBAgahA4WtINivBQrvDe3vAAegD8jQrl8iPjUwoAvvpJK0lAA

💻 Code

declare function fnDerive<A extends unknown[], R>(
    fn: (...args: A) => Generator<unknown, R>,
): unknown /** mocked return */;

fnDerive(function *(a = 0, b = '') {
  console.log({
    a,
 // ^?
    b
 // ^?
  });
});

🙁 Actual behavior

The type of a and b is unknown.

image

🙂 Expected behavior

The type of a and b should be number and string

Additional information about the issue

I was working with a library gensync when I hit this issue, and I extracted the minimum reproduction out of it.

Note that if I don't use default parameters, typescript can infer the a and b types correctly:

declare function fnDerive<A extends unknown[], R>(
    fn: (...args: A) => Generator<unknown, R>,
): unknown /** mocked return */;

fnDerive(function *(a?: number | undefined, b?: string | undefined) {
  console.log({
    a,
 // ^?
    b
 // ^?
  });

  a ??= 0;
  b ??= '';
  console.log({
    a,
 // ^?
    b
 // ^?
  });
});
image
@Andarist
Copy link
Contributor

Andarist commented Aug 15, 2024

This is not specific to generator functions. It's related to inferring type parameters from unannotated parameters with inferred types from initializers (TS playground):

declare function fnDerive<A extends unknown[]>(fn: (...args: A) => void): A;

const result = fnDerive(function (a = 0, b = "") {});
//    ^? const result: [a?: unknown, b?: unknown]

declare function fnDerive2<A, B>(fn: (a: A, b: B) => void): [A, B];

const result2 = fnDerive2(function (a = 0, b = "") {});
//    ^? const result2: [unknown, unknown]

It's also just related to how there is a contextual signature available here. This touched on what I improved here: #56506 . This PR didn't break it anyhow when it comes to the case presented here but it also didn't improve it.

So the question here is also - how both situations should be differentiated? There are situations in which the contextual parameter type should be preferred. Perhaps it could be done based on checkMode & CheckMode.Inferential, or maybe based on the uninstantiated contextual signature when the parameter's type is a type variable.

I'd love to experiment with this but I have a long list of things to experiment with so no promises 😅

@SukkaW SukkaW changed the title TypeScript can't infer type of default parameters in generator functions TypeScript can't infer type of default parameters in factory functions Aug 15, 2024
@SukkaW SukkaW changed the title TypeScript can't infer type of default parameters in factory functions TypeScript can't infer type of default parameters Aug 15, 2024
@SukkaW
Copy link
Author

SukkaW commented Aug 15, 2024

This is not specific to generator functions.

Updated title and search terms to reflect this~

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases labels Aug 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Projects
None yet
Development

No branches or pull requests

3 participants