Open aluanhaddad opened 7 years ago
but any
is more than {}
technically speaking, if we take it to absurd level it's no different than asking to replace any
with HTMLDivElement
why {}
?
(might have been {} | null | undefined | void
or {} | null | undefined | void | boolean | string | number | Date | Regexp | []
for that matter)
Perhaps he wants any
=> all the members that are currently accessed
?
function log(x: any) {
console.log(x.bar.baz);
}
=>
function log(x: {bar: {baz: any}}) {
console.log(x.bar.baz);
}
That said the original suggestion is easily done in most editors with expand selection
+ {
+ delete
shortcuts e.g. alm:
I do this quite commonly myself as well to cleanup existing JS code to discover how the argument is actually used :rose:
@basarat what is the competitive advantage of atom compared to vscode?
@aleksey-bykov alm
(not atom). Most devs have their own setup to help them work better / easily / faster / work the way they do. I just shared mine as alm. Features are covered here https://basarat.gitbooks.io/alm/content/. Trying it is easy npm install alm -g
so give it a go ... or not .. be happy :heart: :rose:
I forgot I wrote the reasons : https://basarat.gitbooks.io/alm/content/contributing/why.html . Been a while since someone has asked :)
I think it would be a good idea for tslint
I apologize for not providing more context and not explaining my primary use case.
As we know, --noImplicitAny
generates errors when a declaration implicitly has type any
. To resolve these errors, it is necessary to add a type annotation.
Implicit any
s arise in different scenarios.
In some scenarios, typically function declarations, we know what the type is but the compiler has not inferred it. In such cases it is only natural to annotate it with that the type we know it should be, e.g. HTMLElement | undefined | null
.
However, in other scenarios we do not yet know, do not yet care, or have not yet decided what the type should be. In such cases it is tempting to explicitly annotate with any
. As surrounding code solidifies we might discover or decide on a more specific type, but because we previously used any
, we are not warned by the compiler.
Here is an example:
function log(x: any) {
console.log(value); // seems fine.
}
Now assume we decide that we want to log the name
property of x
.
function log(x: any) {
console.log(x.name);
}
In the above code, our function has changed its requirements but will continue to accept values that do not have a name
property, so the interface of the function is wrong. Furthermore we will not get an error for accessing the name property of a value that very well may not have one, so the implementation of function is also incorrect.
Due to the viral nature of any
, this problem compounds over time such that a piece of code may be littered with explicit any
s, but implicit assumptions on what the annotated values represent. These persist even when the use of the values so annotated naturally implies a structure and a set of requirements.
If {}
we used instead we would satisfy the typechecker initially and we would still receive errors indicating that we should evolve the type of the value as soon as we begin to make more specific demands on it.
Having a refactoring would encourage this. This request is about code style.
Perhaps he wants any => all the members that are currently accessed?
@basarat indeed that is the spirit of this suggestion. That would be a great feature.
but any is more than {} technically speaking
@aleksey-bykov indeed. I want less not more. any
is a hammer. This is about incrementally updating the type of a value.
aside from you usecase which makes sense, {}
is generally speaking not assignable from null
and undefined
, which are quite common valid options, how would it be like outside of your case?
furthermore it's rather trivial to decontaminate your code from any
either by linting (ts.SyntaxKind.AnyKeyword
) or full text search
// before
function log(value: any) {
}
log(null); // <-- valid case
// after
function log(value: {}) { // <-- any replaced to {} with help of the code action
}
log(null); // <-- no longer compiles, although still theoretically valid
@aleksey-bykov
{} is generally speaking not assignable from null and undefined, which are quite common valid options, how would it be like outside of your case?
That is a great point. Indeed you have clarified that what I actually want is not {}
but rather {} | null | undefined
, which certainly changes things (at least in terms of verbosity)
furthermore it's rather trivial to decontaminate your code from any either by linting (ts.SyntaxKind.AnyKeyword) or full text search
@xLama Suggested linting as well. Perhaps that is where this idea belongs.
i gave it a second thought, i might be helpful if such code action looked for all places that call this function and tried to deduce the replacement type out of all possible arguments out there
// before
function log(value: any) {
}
log(1);
log('a');
// after code action
log(value: number | string) {
}
log(1);
log('a');
I have renamed this issue to reflect the far more useful refactoring proposed by @aleksey-bykov in his remarks above.
The proposed refactoring would look at how a value implicitly typed as any
is used, determine a candidate type from these use sites, and annotate this value explicitly with that type.
Addressed by https://github.com/Microsoft/TypeScript/pull/14786
Can this issue be closed? It sounds like it's been addressed.
nope. i need to update https://github.com/Microsoft/TypeScript/pull/14786, get it reviewed and merged.
Still super excited about this feature. Thanks @mhegazy
I just read #14786, and am also incredibly excited to start using this feature! Out of curiosity, any reason not to use the same feature for implicitly inferring function parameters rather than assuming any unannotated inputs are type any
? In other words, in addition to the Quick Fix, could the compiler use the inferred type instead of any
even without the annotation? I feel as though that kind of static analysis could help TypeScript catch a lot of bugs on old javascript code bases that don't have any annotations.
I would very much appreciate having a codefix (refactoring) that, given an explicit
any
annotation, offers to change it to an{}
annotation.For example, given
a code fix would be offered to change the declared type of
x
to{}
resulting inHowever, given
a code fix would be offered to change the declared type of
x
to{ name: any }
resulting in