Skip to content

Error span incorrect when this constraint on member function failsΒ #60709

@SebastienGllmt

Description

@SebastienGllmt

πŸ”Ž Search Terms

  • error span
  • this: never
  • this chain
  • builder pattern

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried (including the latest 5.7.2)

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.8.0-dev.20241206#code/PQKhCgAIUhZBTAtgI3gJ0gMwK4DsDGALgJYD2ukyAhgM7wAmk+t8UIw4+ANrTZAGJ4iZXACEW9UdmJd66ADwBlQvAAOkeAA8Vuen1zYU6ALwBGAHyQA3lEg0Vq0wApCAC2I0AXJGVqN2+F0+U0gAfkg3D0hvXHgAN3QASm9BAhJycTpJaVkFACZLG0hiyDR4Qmw0Cki+WkgqXABPAG5bAF9bezU8l3cvHwd-HT1IPLCIvujIWIS0ZIEhdLEJKRk5NHkAZkLbYrKKqomouoaW9ttgYDsAa2J1LvVN-1UuYnxiQi5GiNJIOURyPY0FQVBN4Bo0GhSGhOg4ACy9DzeXzqLTDPhw8Y1KYzJIpRYiTIMVa5DYAVh2JVK5Uq1UmJyarWKHQ64FAEGgcCQqAwcSoaGIVGQXHB1CyTBYbA43F4kAAavzBcL4ETsmsFCihoERgYjGgzJS7A5TN4nJq0drguMnIlIMZLAqBUKRaqSet5AUcfEknbIE4bXbDXsaYdsQyzszbeGmUbuqbzQEgqNrbb7fLFc6VSscu7tl7Zqm-QG00USvtaUdarVGe0o9WI5BLjc7rHHs9Xu9Pt9CL9-oDCMDQW5wegoTDig84fHBhak5jwsWHRnla6cwoKfmfcYi6mg9SDnTjvWY206-Ua6z8P2sEI3ehfbEAO4LNKE7PqtA21pNqhcLiQUhMEgAADTBSFIAA6B5nESKCHB6RJgIiWk+GIXAe3PSA8FceAuFUHB-1HaFIEQeAaBoKgAHNWBwAg7zQOC1BgxjVAQliEUSVpOGvPk0Hoh94GfR0lRdd9SS-NkrmHCEx0gVQoVUdAvnqVRFP5PhyGU8hW0gOFwF4+iWOYh42MnL8gA

πŸ’» Code

/**
 * Member function based case
 */
class FunctionBasedBuilder<Step extends number=1> {
  step1(this: Step extends 1 ? this : never): FunctionBasedBuilder<2> {
    return this as any;
  }
  step2(this: Step extends 2 ? this : never): FunctionBasedBuilder<3> {
    return this as any;
  }
  // skip step 3 explicitly to demonstrate the error
  step4(this: Step extends 4 ? this : never): FunctionBasedBuilder<5> {
    return this as any;
  }
}

/**
 * Member variable based case
 */
class VariableBasedBuilder<Step extends number=1> {
  step1: (Step extends 1 ? () => VariableBasedBuilder<2> : never) = (() => {
    return this as any;
  }) as any;
  step2: (Step extends 2 ? () => VariableBasedBuilder<3> : never) = (() => {
    return this as any;
  }) as any;
  // skip step 3 explicitly to demonstrate the error
  step4: (Step extends 4 ? () => VariableBasedBuilder<5> : never) = (() => {
    return this as any;
  }) as any;
}

const funcBuilder = new FunctionBasedBuilder();
// all of `foo.step1().step2()` turns into an unhelpful error message
funcBuilder.step1().step2().step4();

const varBuilder = new VariableBasedBuilder();
// the error properly appears only on step 4
varBuilder.step1().step2().step4();

πŸ™ Actual behavior

In the function case, the entire span from foo.step1().step2() gets marked as an error instead of only step4() which is what actually caused the error

πŸ™‚ Expected behavior

Just like in the member variable case, it would be better if the error was shown on step4()

Additional information about the issue

I think this ends up being equivalent to #28159 so I'm not sure it can be solved without introducing the "curse" mentioned in #60140

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Related Error SpansSpecifying regions for error messages/diagnostics on multiple locations.Help WantedYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions