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

Return type is any of getter in object passed as generic #49511

Open
jakst opened this issue Jun 13, 2022 · 2 comments
Open

Return type is any of getter in object passed as generic #49511

jakst opened this issue Jun 13, 2022 · 2 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@jakst
Copy link

jakst commented Jun 13, 2022

Bug Report

When the following is true:

  • You are passing an object created inline to a function
  • The type of that function argument is generic
  • The object has a getter that accesses this
  • The object also has a function

Then the return type of the getter will be any.

If you either remove the function from the object or create the object before passing it into the function the getter will return the correct type.

🔎 Search Terms

any, object, generic

🕗 Version & Regression Information

  • Bug present in all versions available on the playground, including nightly

⏯ Playground Link

Playground link with relevant code

💻 Code

declare function generic<T>(v: T): T;

// Passing object directly to genery gives type `any` on `get hi()`
const store = generic({
  hello: "hi",

  // return type of getter is any
  get hi() {
    return this.hello;
  },

  // If you remove this function, return type of getter will be string
  doSomething() { }
});

const res = store.hi // any

// Passing object directly to genery gives type `any` on `get hi()`
const obj = {
  hello: "hi",

  // return type of getter is string
  get hi() {
    return this.hello;
  },

  doSomething() { }
};
const store2 = generic(obj)

const res2 = store2.hi // string

🙁 Actual behavior

Return type of getters are any

🙂 Expected behavior

Return type of getters have the type of the returned data

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Jun 13, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jun 13, 2022
@RyanCavanaugh RyanCavanaugh added the Help Wanted You can do this label Jun 13, 2022
@craigphicks
Copy link

craigphicks commented Jun 14, 2022

Looks related -- from src/compiler/checker.ts, resolveCallExpression(...)

// When a call to a generic function is an argument to an outer call to a generic function for which
// inference is in process, we have a choice to make. If the inner call relies on inferences made from
// its contextual type to its return type, deferring the inner call processing allows the best possible
// contextual type to accumulate. But if the outer call relies on inferences made from the return type of
// the inner call, the inner call should be processed early. There's no sure way to know which choice is
// right (only a full unification algorithm can determine that), so we resort to the following heuristic:
// If no type arguments are specified in the inner call and at least one call signature is generic and
// returns a function type, we choose to defer processing. This narrowly permits function composition
// operators to flow inferences through return types, but otherwise processes calls right away. We
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
// propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and
// from which we never make inferences).
if (checkMode & CheckMode.SkipGenericFunctions 
    && !node.typeArguments 
    && callSignatures.some(isGenericFunctionReturningFunction)) {
    skippedGenericFunction(node, checkMode);
    return resolvingSignature;
}

@lqzhgood
Copy link

lqzhgood commented May 9, 2024

#58483

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

4 participants