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

Twoslash and $ExpectType have different behavior #74

Open
OliverJAsh opened this issue Mar 17, 2023 · 2 comments
Open

Twoslash and $ExpectType have different behavior #74

OliverJAsh opened this issue Mar 17, 2023 · 2 comments
Labels
status: needs investigation Further research required...?

Comments

@OliverJAsh
Copy link

OliverJAsh commented Mar 17, 2023

🐛 Bug Report

  • eslint-plugin-expect-type version: 0.2.2
  • ESLint version: 8.36.0
  • Node version: 16.3.0

Actual Behavior

Full reduced test case here: https://github.com/OliverJAsh/eslint-plugin-expect-type-issue

Contents inlined below.

package.json:

{
  "dependencies": {
    "@typescript-eslint/parser": "^5.55.0",
    "eslint": "^8.36.0",
    "eslint-plugin-expect-type": "^0.2.2",
    "typescript": "^5.0.2"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "strict": true
  }
}

.eslintrc.js:

const path = require("path");

module.exports = {
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: path.join(__dirname, "./tsconfig.json"),
  },
  plugins: ["eslint-plugin-expect-type"],
  rules: {
    "expect-type/expect": "error",
  },
};

source.ts:

export type Compact<A> = A extends Function ? A : { [K in keyof A]: A[K] } & {};

test.ts:

import { Compact } from "./source";

declare const any: any;

const x: Compact<Record<"a" | "b", number> | Record<"a" | "c", number>> = any;

// ❌ Error:
//  Expected type to be: { a: number; b: number; } | { a: number; c: number; }, got: Compact<Record<"a" | "b", number> | Record<"a" | "c", number>>
// $ExpectType { a: number; b: number; } | { a: number; c: number; }
type Test1 = typeof x;

// ✅ No error
type Test2 = typeof x;
//   ^? type Test2 = {
//          a: number;
//          b: number;
//      } | {
//          a: number;
//          c: number;
//      }
  • $ExpectType expects: Compact<Record<"a" | "b", number> | Record<"a" | "c", number>>
  • Twoslash expects:
       type Test2 = {
        a: number;
        b: number;
    } | {
        a: number;
        c: number;
    }

I believe the reason for this difference is because Twoslash and $ExpectType use different mechanisms to generate the "actual" value:

This particular issue started after we upgraded to TypeScript 5. Prior to this, $ExpectType had the same behavior as Twoslash in this particular example. I'm not sure why this has changed.

Expected Behavior

Twoslash queries and $ExpectType should behave the same.

Reproduction

https://github.com/OliverJAsh/eslint-plugin-expect-type-issue

@danvk
Copy link
Collaborator

danvk commented Mar 17, 2023

Thanks for the report @OliverJAsh. Do you think its expected (by the TS team) that the behaviors of getQuickInfoAtPosition and typeToString have diverged? Should we file an upstream issue about it?

Assuming this is intentional… while it is curious, I'm not sure this is undesirable behavior? I would expect $ExpectType to behave the same way as dtslint. And I'd expect twoslash-style assertions to behave the same way they do in the TypeScript playground. Which I believe is the case right now, even though those two have diverged.

@OliverJAsh
Copy link
Author

Do you think its expected (by the TS team) that the behaviors of getQuickInfoAtPosition and typeToString have diverged?

Good question. I honestly have no idea. Up until now, my mental model for $ExpectType has always been it will use the same printed string as what you see when you hover over a type or use Twoslash, but maybe I was wrong to think that.

@JoshuaKGoldberg JoshuaKGoldberg added the status: needs investigation Further research required...? label May 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs investigation Further research required...?
Projects
None yet
Development

No branches or pull requests

3 participants