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

Why TypeScript ReturnType returned sequence is unstable in vscode #51517

Closed
Eve-Sama opened this issue Nov 12, 2022 · 17 comments
Closed

Why TypeScript ReturnType returned sequence is unstable in vscode #51517

Eve-Sama opened this issue Nov 12, 2022 · 17 comments
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@Eve-Sama
Copy link

Does this issue occur when all extensions are disabled?: Yes/No

  • VS Code Version: 1.73.0 (Universal)
  • OS Version: Mac 12.5.1

Steps to Reproduce:

type A = () => 'a';
type B = () => 'b';
type Res1 = ReturnType<A | B>;
type Res2 = ReturnType<B | A>;

It's weird that above code run in vscode. I think the Res1 and Res2 is different. But they always keep same output. Sometimes they are 'a' | 'b', sometimes they are 'b' | 'a'. I have to restart vscode window or restart ts server trying to get right output. Is this a vscode bug?

图片

图片

@VSCodeTriageBot
Copy link

Thanks for creating this issue! It looks like you may be using an old version of VS Code, the latest stable release is 1.73.1. Please try upgrading to the latest version and checking whether this issue remains.

Happy Coding!

@Eve-Sama
Copy link
Author

It still exist in 1.73.1

@Eve-Sama
Copy link
Author

Eve-Sama commented Nov 12, 2022

I know they are same when used as union type. I wonder why the result is unstable? Different time display different sequence.

@Okaretkina7
Copy link

Does this issue occur when all extensions are disabled?: Yes/No

  • VS Code Version: 1.73.0 (Universal)
  • OS Version: Mac 12.5.1

Steps to Reproduce:

type A = () => 'a';
type B = () => 'b';
type Res1 = ReturnType<A | B>;
type Res2 = ReturnType<B | A>;

It's weird that above code run in vscode. I think the Res1 and Res2 is different. But they always keep same output. Sometimes they are 'a' | 'b', sometimes they are 'b' | 'a'. I have to restart vscode window or restart ts server trying to get right output. Is this a vscode bug?

图片 图片

@Eve-Sama
Copy link
Author

Yes, it occur when all extensions are disabled. And it occur in my friends.

@Eve-Sama
Copy link
Author

图片

图片

It works fine in IDEA

@Dimava
Copy link

Dimava commented Nov 12, 2022

@Eve-Sama you didn't provide your TS version, and it's 3.x?

@Eve-Sama
Copy link
Author

"typescript": "^4.8.3"

@Eve-Sama
Copy link
Author

Eve-Sama commented Nov 12, 2022

TypeScript version is 4.8.4 via package.json from node_modules

@Dimava
Copy link

Dimava commented Nov 12, 2022

try

type A = () => 'a';
type B = () => 'b';
type C = () => 'c';
type D = () => 'd';

type x = [
  // ^?
    ReturnType<A | B>,
    ReturnType<B | A>,
    ReturnType<D | C>,
    ReturnType<C | D>,
]

It seems that I can't make an array with different ones, but the order depends on which one was instantiated earlier

@Eve-Sama
Copy link
Author

export type TestFn = <T extends ReadonlyArray<() => string>>(request: T, thenCallback: (data: ReturnType<T[number]>) => void) => void;
const fnA: () => 'a' = () => 'a';
const fnB: () => 'b' = () => 'b';
const fnC: () => 'c' = () => 'c';
const fnD: () => 'd' = () => 'd';
const fn: TestFn = (requestList, thenCallback) => {
  console.log(requestList, `requestList`);
  console.log(thenCallback, `thenCallback`);
};

fn([fnA, fnB, fnC, fnD], data => {
  console.log(data, `data`);
});

图片

This bug lead to this trouble.

@IllusionMH
Copy link
Contributor

TS doesn't provide any guarantees about union members order. Always been this way.

Basically duplicate of #17944

@Eve-Sama
Copy link
Author

TS doesn't provide any guarantees about union members order. Always been this way.

Basically duplicate of microsoft/TypeScript#17944

But why random?

@Dimava
Copy link

Dimava commented Nov 14, 2022

@Eve-Sama not "random", but "instantiation order"
It's not sorted, and the first result is considered to be correct

@mjbvz mjbvz transferred this issue from microsoft/vscode Nov 14, 2022
@mjbvz mjbvz removed their assignment Nov 14, 2022
@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Nov 14, 2022
@Eve-Sama
Copy link
Author

If it's ts's feature, Why it works fine in IDEA?

@fatcerberus
Copy link

I think IDEA uses its own language service that's based on the official one but with enhancements/customizations so it doesn't always behave the same. Even so, this is just about display order - A | B and B | A are exactly the same type to the compiler.

@Eve-Sama
Copy link
Author

const fnA: () => 'a' = () => 'a';
const fnB: () => 'b' = () => 'b';
const fnC: () => 'c' = () => 'c';
const fnD: () => 'd' = () => 'd';
const fn: TestFn = (requestList, thenCallback) => {
  console.log(requestList, `requestList`);
  console.log(thenCallback, `thenCallback`);
};

fn([fnA, fnB, fnC, fnD] as const, data => {
  console.log(data, `data`); // data: "a" | "b" | "c" | "d"
});

I have found how to make it works. Just need to add as const.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a Defect This behavior is one of several equally-correct options
Projects
None yet
Development

No branches or pull requests

8 participants