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 inference failed #56855

Open
LiST-GIT opened this issue Dec 23, 2023 · 3 comments
Open

Generic type inference failed #56855

LiST-GIT opened this issue Dec 23, 2023 · 3 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@LiST-GIT
Copy link

LiST-GIT commented Dec 23, 2023

πŸ”Ž Search Terms

Generics

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABKSAeAUIriAqBGAGk2xwGZEBTADygrABMBnRAb0QG0BrCgTwC5EjKACcYYAOYBdAQAoICWjQH4AlIgC8APkQA3ODHqIAvkWy4ALBtYnEAeluIAwnAC2LurAmI4IKIigAFjDMjBTQ8EhwwIjy9BSILgCG3MwwfgDucMKciAAOwnC5FMIANjwAdOiaMvSJUIkCLMRYOMp4ANzNiADSyuQAZLhBjDg8Raj4iINkmp1Gak1G6OgoEDJNZq2sXWYARvsCeABMpKZm2ImXMguIwhRQIMJIpC-txmdYJl292+fY+7s5ApqFAFjs-jEEIw4CUKOUSnBxECwIooOVLolripOhDzvIwNDYfDEcjUeUAdjwX9AsFyhB6dccRCvrj6WsbizsF95u0gA

πŸ’» Code

function func<
    T1,
    T3 extends { [key: string]: (context: T1) => void },
    T4 = {}, // Commenting out this section of code makes it work properly.
>(data: {
    T: T1;
    K: T3 & ThisType<T1 & T3>;
}) {
}

func({
    T: {
        bbb: 123,
        aaa() { return 333; },
    },
    K: {
        bbb(context) {
            console.log(context.aaa());
            console.log(context.bbb);
            this.ccc();
        },
        ccc() { },
    },
});

πŸ™ Actual behavior

display an error message:

'context' is of type 'unknown'.
'context' is of type 'unknown'.
'T4' is declared but its value is never read.
'data' is declared but its value is never read.

πŸ™‚ Expected behavior

The type of 'context' should already be determined; it shouldn't be 'unknown'.

Additional information about the issue

No response

@LiST-GIT LiST-GIT changed the title generic type inference failed Generic type inference failed Dec 24, 2023
@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Jan 2, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jan 2, 2024
@jfet97
Copy link
Contributor

jfet97 commented Jan 3, 2024

The following seems to work:

function func<
    T1,
    T3 extends { [key: string]: (context: T1) => void },
    T4 = {},
>(data: {
    T: T1;
    K: T3 & ThisType<T1 & T3>;
}) {
}

func({
    T: {
        bbb: 123,
        aaa: () => { return 333; }, // <-- here lies the difference: arrow instead of method
    },
    K: {
        bbb(context) {
            console.log(context.aaa());
            console.log(context.bbb);
            this.ccc();
        },
        ccc() { },
    },
});

Playground

@Andarist
Copy link
Contributor

Andarist commented Jan 4, 2024

This likely belongs to this umbrella issue: #47599

@jfet97
Copy link
Contributor

jfet97 commented Jan 4, 2024

The problem is the following if inside instantiateContextualType:

// If no inferences have been made, and none of the type parameters for which we are inferring
// specify default types, nothing is gained from instantiating as type parameters would just be
// replaced with their constraints similar to the apparent type.
if (
  inferenceContext &&
  contextFlags! & ContextFlags.Signature &&
  some(inferenceContext.inferences, hasInferenceCandidatesOrDefault)
) {
    // For contextual signatures we incorporate all inferences made so far, e.g. from return
    // types as well as arguments to the left in a function call.
    return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
 }

The condition results true at the wrong time, too eagerly as far as I understand it, therefore stuff gets instantiated with some default types.

If you change the condition in one of the two following ways you solve this specific issue, but you get failing baselines:

  1. !some(inferenceContext.inferences, hasInferenceCandidatesOrDefault) seems somewhat more related with the above comment (?), but you get too many failing baselines
  2. every(inferenceContext.inferences, hasInferenceCandidatesOrDefault) just a couple of failing baselines, but one of them is about contextual inference and, guess what, it works here but not there anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

4 participants