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

"Implicitly has type 'any'" when type annotation is provided #50864

Closed
turolla opened this issue Sep 20, 2022 · 6 comments
Closed

"Implicitly has type 'any'" when type annotation is provided #50864

turolla opened this issue Sep 20, 2022 · 6 comments
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@turolla
Copy link

turolla commented Sep 20, 2022

Bug Report

πŸ”Ž Search Terms

implicit any, filter object properties by type, key remapping

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type BooleanProperties<T> = T extends any ? { 
  [K in keyof T as T[K] extends boolean ? K : never]: boolean;
} : never;

class Foo {
  booleansOnly: BooleanProperties<this> = undefined!; // Omitted..
  
  getString<F extends (someUsefulData: any) => any>(fn: F) : string {
    return undefined!; // Omitted..
  };

  aBoolean = true;
  
  definitelyAString = this.getString(() => this.booleansOnly.aBoolean);
}

πŸ™ Actual behavior

Error: 'definitelyAString' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

πŸ™‚ Expected behavior

Since "getString" method has an explicit return type (string), in my opinion "type annotation" is provided, and the error should not be thrown.

@MartinJohns
Copy link
Contributor

MartinJohns commented Sep 20, 2022

The magic words are:

is referenced directly or indirectly in its own initializer.

You're initializing definitelyAString with an expression calling this.booleansOnly, which requires the type of booleansOny to be known. This type is using the polymorphic this type, so the compiler must know what this looks like. For this it needs to know the type of definitelyAString.

in my opinion "type annotation" is provided

But... There is no type annotation provided. You assume the type can be inferred, but there's no type annotation. A type annotation would look like this:

definitelyAString: string = ...

The : string part is the type annotation. Your property does not have it. See also: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-annotations-on-variables

@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Sep 20, 2022
@RyanCavanaugh
Copy link
Member

The chain of circularity is as follows:

  • What is the type of definitelyAString ?
  • What is the type of the call to getString ?
    • Note: It's not sufficient to say "string, obviously!" -- the call needs to be processed to check for errors, contextually type the arguments, etc; this cannot be arbitrarily deferred
  • What is the type of () => this.booleansOnly.aBoolean ?
  • What is the type of this.booleansOnly ?
  • What is the type of definitelyAString ? <- circular

@turolla
Copy link
Author

turolla commented Sep 21, 2022

Thank you very much @MartinJohns and @RyanCavanaugh for your very kind and complete answers.
I hope in the future Typescript will provide a way to handle this kind of sistuations, in the same way nowadays it's possibile to write

definitelyAString = this.getString(() => this.booleansOnly);

without getting errors.
Maybe adding some kind of syntax to provide Typescript instructions on how to handle circularity errors, for example something like:

type BooleanProperties<T> = { 
  [K in keyof T as 
    T[K] extends CircularType ? never : // <-- Typescript, if you you have circularity problems, then...
      T[K] extends boolean ? K : never]: boolean;
};

Have a nice day.

@MartinJohns
Copy link
Contributor

Maybe adding some kind of syntax to provide Typescript instructions on how to handle circularity errors

It mentioned the option to add a type annotation in the error message.

I hope in the future Typescript will provide a way to handle this kind of sistuations

As far as I know the compiler would have to be rewritten basically from scratch, and introduce a two-phase type check. Very unlikely to happen.

@RyanCavanaugh
Copy link
Member

There's a good discussion about this in #45213

@github-actions
Copy link

github-actions bot commented Jun 8, 2023

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

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 8, 2023
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

3 participants