microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.85k stars 12.36k forks source link

spread operator infer to wrong type with method override and generic #59281

Closed syi0808 closed 4 weeks ago

syi0808 commented 1 month ago

šŸ”Ž Search Terms

generic spread

šŸ•— Version & Regression Information

āÆ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.3&ssl=9&ssc=72&pln=10&pc=79#code/C4TwDgpgBAsg9gYwNYDECGDhwE4gOoCWwAFgBIQA2k2APDFALxQCuAdkq3AO6sB8jUABQBYAFBQoBALZgcwAPLYCAcwKs0FAFw0AKlAgAPYBFYATAM6wBMXoICUjfgAVscKQXMRdvMQ4bO0bGACDRoAJQgEHFMaJAgQOAAzWAAaKDRWEF4fUVBIKBc3Dwh4ZHRMHHwiMkpqOgE2Dm4+ARFxSRk5RRU1DU0oXX0jEwsrJht7RwLXd09vXynC2a8nQODQiKjsGLiE5Jg0jKzssTEo1nNgFmCtKABvMQkpRCRvQWfTZgoIfqXi7zSiQwWFwAH5+qVUMDKoQSOQqBBaDpeHZ+gA3OAEUyPKDPZBvD5fH7TIpzZGA6Fg34zYqQ8ogqpw2qI7yoqAYrFiAC+Age7TxSH6gkm-nuXIcaEsR25AG5TqJBJKQKwEFBEmxMAQ4KxJnyJMwbgA6AWCaSyIKCADkYDQJEtdkO5mVqtNnSC3VU6gofn4gj1EighqDiq4aCIHXNCiUno09jsOPFdjlonF9hlQA

šŸ’» Code

type MockFactoryWithHelper<M = unknown> = (
  importOriginal:<T extends M = M>() => Promise<T>
) => Partial<Record<keyof M, any>>
type PromiseMockFactoryWithHelper<M = unknown> = (
  importOriginal: <T extends M = M>() => Promise<T>
) => Promise<Partial<Record<keyof M, any>>>

const util: {
  mock<T>(module: Promise<T>, factory?: MockFactoryWithHelper<T>): void
  mock<T>(module: Promise<T>, factory?: PromiseMockFactoryWithHelper<T>): void
} = {
  mock: (() => {}) as any
};

(async function() {
  util.mock(import('path'), async (importOriginal) => ({
    ...(await importOriginal())
  }));
})();

šŸ™ Actual behavior

Typescirpt throw error like Spread types may only be created from object types.(2698); on line spread syntax

šŸ™‚ Expected behavior

Typescirpt should not throw error on inline spread syntax.

Additional information about the issue

No response

RyanCavanaugh commented 1 month ago

The error here is because you're trying to spread a never. This is not a syntax error.

syi0808 commented 1 month ago

The error here is because you're trying to spread a never. This is not a syntax error.

But it works well on version before 5.3.0-dev.20231027. And return value of importOriginal should never be infer as never type.

That's right. I changed the title.

syi0808 commented 1 month ago

And if this is an unintended bug, I would love to contribute. Where can I find the changes to the 5.3.0-dev.20231027 distribution version?

RyanCavanaugh commented 1 month ago

every-ts can bisect to a specific commit https://github.com/jakebailey/every-ts

syi0808 commented 1 month ago

I'll try it within a week. Thanks for sharing.

Andarist commented 1 month ago

Given that overloads are generally picked from the top to the bottom. Shouldn't this be fixed at the definition site of this mock method? If you swap those overloads it works OK: TS playground

Similarly, it works OK if you combine those 2 overloads into a single signature: TS playground. This solution should be preferred over the first one.

RyanCavanaugh commented 1 month ago

I agree with @Andarist 's comments in the PR - this doesn't seem like a bug.

typescript-bot commented 4 weeks ago

This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes.