Skip to content

Generic types can't have some types inferred if they are derived from another generic which doesn't necessarily use them. #44525

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

Closed
SephReed opened this issue Jun 9, 2021 · 2 comments

Comments

@SephReed
Copy link

SephReed commented Jun 9, 2021

Bug Report

πŸ”Ž Search Terms

Generics, infer, derived, unused, doesn't work

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type A<T, Y, Z> = () => true;  // this does not work
// type A<T, Y, Z> = () => T;  // this works

type InferT<I> = I extends A<infer T, any, any> ? T : never;

// typeof directInfer is "true"
let directInfer: InferT<A<true, null, null>>; // this works either way


type B<T> = A<T, null, null>;
const test: B<true> = () => true;

// typeof indirectInfer is "uknown"
// should be of type "true", and it works if you uncomment the line above
let indirectInfer: InferT<typeof test>;

πŸ™ Actual behavior

  • If you make a generic A which does not necessarily use all of its arguments, then instantiate a variable of that type, you can still use infer to pull out every generic argument from it.

  • If you then make a new generic B which is a version of A with some fields pre-filled, then use the same inference function as for A, it will no longer work on generic arguments which are not used in A.

  • If you then change A to use all of its generic arguments, inferring from B will now work.

πŸ™‚ Expected behavior

It shouldn't matter whether or not the base generic A uses a generic field. If it can be inferred one way, it should be able to be inferred either way.

@jcalz
Copy link
Contributor

jcalz commented Jun 10, 2021

This is working as intended; see this FAQ entry. TypeScript's type system is structural and not nominal; if a type doesn't depend structurally on T, then in principle you can't infer T from it. (In practice, sometimes the compiler can do this, but it really shouldn't be relied upon).

See #40796, #26815

@SephReed
Copy link
Author

Ah. I suppose that makes sense. Luckily I found a way of getting around my issue so I guess I'll close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants