4

Consider the following typescript code:

function eatString(str: string){
    console.log(str);
}

const anyObject: any = {
    junk: 3425234,
};

eatString(anyObject); // Compiles ok - by why?
eatString({something: "abc"}); // Doesn't compile - as expected

Is there a way to prevent the function eatString(str: string) from taking an any argument, either by tsconfig or tslint options or otherwise?

I initially thought that noImplicitAny might help but after trying it and reviewing the documentation it wasn't what I thought. no-any isn't an option for me as I still want to be able to use any in some cases.

If this isn't possible, is there some reason that I'm missing as to why? I haven't been working in typescript/javascript for very long, but I've already been caught out a few times by some issues that this would have prevented.

valjean
  • 53
  • 1
  • 2
  • 4
  • The whole idea of `any` is that it it is the one type that can represent any JavaScript value with no constraints. https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.1 – Oram Nov 19 '18 at 08:49

1 Answers1

4

any by definition is assignable to any other type, so when you pass anyObject to the parameter str it will be compatible as per this rule.

You should avoid using any unless absolutely necessary. If you don't know the type you should use unknown which is not compatible to other types without a guard or an assertion (see here for differences with any)

function eatString(str: string){
    console.log(str);
}

const anyObject: unknown = {
    junk: 3425234,
};

eatString(anyObject); // error now

In this particular case you should just let the compiler infer the type for anyObject

function eatString(str: string){
    console.log(str);
}

const anyObject = { // inferred as { junk : number }
    junk: 3425234,
};

eatString(anyObject); // error now

You could use tslint to forbit the usable of any as a type annotation (using this rule) but any might stillleak in from external APIs.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • Somehow I missed the `unknown` type, which in combination with tslint's `no-any` solves my problem. Initially I was seeing `any` as what `unknown` really is, but I understand now. Thanks! – valjean Nov 19 '18 at 10:13
  • @valjean glad to help, don't forget to upvote and mark as answered if it was useful :) – Titian Cernicova-Dragomir Nov 19 '18 at 10:14
  • In my case, `any` did leak from the external library and I'm looking for a way to prevent passing it to functions. I'm in strict mode and noImplicitAny is on, but still no compilation error. – Maxim Mazurok Feb 24 '22 at 00:51