47

When I compile my typescript project, I'm using the noImplicitAny option so that I won't forget to specify the types on my variables and arguments.

However sometimes you have arguments that you don't use. For example:

jQuery.ajaxTransport("+*", function (options: JQueryAjaxSettings) {
  return {
    abort: function (_, callback: JQueryCallback) { 

I am not interested in the first argument of the abort function, so I ignore it by naming it _.

Is that the proper way to do that in TypeScript? I couldn't find it in the guide. I suspect that it isn't the proper way, because I can only name one argument _.

Typescript raises the following error:

error TS7006: Parameter '_' implicitly has an 'any' type.

I could just type _:any but that seems a bit overkill for an argument that I don't use.

Yvo
  • 18,681
  • 11
  • 71
  • 90
  • 1
    there's no such thing as a default parameter name. if you enabled noImplicitAny you must specify the type for everything. – toskv Aug 08 '16 at 18:12
  • 2
    I am basically looking for the equivalent of Swift's ignored parameter: http://stackoverflow.com/questions/24338045/what-is-the-usecase-for-ignored-parameters-in-swift – Yvo Aug 08 '16 at 18:29
  • 1
    there's no such thing in JS or typescript. :) – toskv Aug 08 '16 at 18:34
  • 1
    @toskv that's unfortunate, but thank you. If you add it as an answer I will accept it :) – Yvo Aug 08 '16 at 20:47
  • 1
    https://github.com/Microsoft/TypeScript/issues/14154 – glen-84 Apr 27 '18 at 19:15

3 Answers3

46

I was having the same problem. Using say express and routing you would often only want the res parameter.

router.get('/', function (req, res) { res.end('Bye.'); });

Your idea of using _ works here, but I've also found doing this works too.

function (_1, _2, _3, onlyThis) { console.log(onlyThis); }

This seems better, as only doing '_' I think might make using lodash/underscore a bit confusing, and it also makes it obvious it's the 4th parameter your interested in.

Update: It's been a long time since I posted this answer, and in the comments I'm getting a few miss conceptions. So though I would clarify.

Using the underscore trick is still very useful in Typescript. Like I mentioned in my original answer say if you was using express and did app.get('/', (req, res) => { you will get a warning 'req' is declared but its value is never read, but if you do -> app.get('/', (_req, res) => { the warning will go away. You should not get the error TS7006: Parameter 'req' implicitly has an 'any' type. error anyway, as @types/express should be implicitly typing this param anyway.

Update 2,. Please note the second answer here using {} for parameters, might look cool, but it's considerable slower, so personally I would be careful using inside tight loops.

Keith
  • 22,005
  • 2
  • 27
  • 44
  • 6
    Would the numbered parameters not also have an implied `any` type? That was the problem that the OP was trying to resolve. – Michael L Perry Mar 14 '18 at 18:23
  • @MichaelLPerry It was to get around this problem -> `because I can only name one argument _.` The underscore trick also works for Linters too. Also at the time not sure how Typescript handled this, currently checking on an unused parameter seems a bit odd anyway, so I'd say if Typescript is still treating underscore params as unused, this warning should not appear. You would now need to do `_1:any, _2:any`.. – Keith Mar 14 '18 at 18:45
  • 1
    Why use numbers instead of something like `_req`? And yes, this doesn't answer the OP's question. – glen-84 Apr 27 '18 at 18:57
  • There is nothing wrong in using `_req`, never said there was. In fact it's what I tend to do now, but my original answer was done Sept 2016. Not sure what Typescript & Linters were doing then, and my Javascript skills were very new then too.. :) – Keith Apr 27 '18 at 20:51
  • 11
    I dont understand why this got the votes: `Parameter '_' implicitly has an 'any' type.` is still a very valid error – phil294 Nov 24 '18 at 14:21
  • 1
    This answer is incorrect. – user2398029 Jan 02 '22 at 19:32
  • @user2398029 It still works for me, I've updated my answer to try an clarify it's usage. – Keith Jan 02 '22 at 20:42
35

I may be late, but I got stuck with the other solutions and this one work all the time for me:

function ({}={}, {}={}, {}={}, onlyThis) { console.log(onlyThis); }

comparison

When using the _0, _1, ... solution, I faced difficulties with scooped function like:

function parent(_0, _1, _2) {
  function child(_0, _1, _2) {
    // TypeScript crying about shadowed variables
  }
}

but with the empty object it work well:

function parent({}, {}, {}) {
  function child({}, {}, {}) {
    // :-)
  }
}

Even if the parameters are typed like:

function parent({}: number, {}: string, {}: any) {
  function child({}: number, {}: string, {}: any) {
    // :-) x2
  }
}

EDIT:

And as written here, setting a default value avoid error throwing if the given parameter is undefined or null.

function parent({}={}, {}={}, {}={}) {
  function child({}={}, {}={}, {}={}) {
    // :-)
  }
}
Miaow
  • 864
  • 9
  • 23
  • 3
    According to the linked answer this only avoids throwing when passing `undefined` not when passing `null`. – user764754 Nov 04 '19 at 10:48
  • So this is using [object destructuring](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#destructuring) for each parameter. For me, I needed to specify the third parameter, so I did something like `({}, e: SomeType) => {/* use e here… */}` – binki Oct 09 '21 at 18:45
  • @hraban If performance is an issue, do bear in mind this is much slower,. So in tight loops I would avoid. – Keith Jun 14 '22 at 09:30
  • this might work but is UGLY ;) – JesseBoyd Jul 11 '23 at 21:18
1

This is absolutely unholy but you can use this:

function fn(...[,,,param]){
  console.log(param)
}
fn(2,3,4,5) //prints(5)
Bobby Morelli
  • 460
  • 2
  • 7