5

I have a function that takes a single argument, which I will call options. I prefer not using the options style (I rather like named arguments) but this is a requirement for now. A type for the items inside the options object is supplied per the TypeScript docs

const doThing = async ({
  query = null
}: {
  query?: string;
}) => {
  var options = Array.from(arguments)[0]
};

This fails with:

Cannot find name 'arguments'.ts(2304)

I don't understand this, as arguments should exist in all JS functions.

How can I use arguments in a Typescript function?`

What I am trying to do:

  • have a single options argument

  • enforce typing and have default values on the data inside

  • be able to access that options argument by a name.

11
  • 3
    I think you want to do (...arguments) => { var options = Array.from(arguments)[0] } Commented Mar 4, 2020 at 17:26
  • May be related: stackoverflow.com/a/12697349/457268 Commented Mar 4, 2020 at 17:27
  • @k0pernikus That would remove all the typings. Additionally the function would no longer take a single options argument, which is a requirement of the question. Commented Mar 4, 2020 at 17:28
  • 4
    Not related to typescript - arrow functions do not have an arguments objects. It is not clear from your example what are you trying to do.. Commented Mar 4, 2020 at 17:45
  • 1
    @AlekseyL. Confirmed via developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. Commented Mar 4, 2020 at 17:51

2 Answers 2

2

As already noted in the comments, arrow functions don't have the reserved arguments variable.

But you can still have type safety, a single named argument and default values if you just split up these requirements into different statements. That will also make the code much easier to read and understand:

interface Options {
    query: string | null;
}

const defaultOptions: Options = {
    query: null,
}

const doThing = async (options: Partial<Options>) => {
    const completeOptions: Options = Object.assign({}, defaultOptions, options);
};

Additionally the Options interface actually specifies the strucure that you need inside the function body this way.

Also you can now pass a partial set of options without having to specify all properties literally twice inline, where the value level of the signature -- { query = null } -- specified the default values before, and the type level -- { query?: string; } -- specified both the types and the fact that option keys are optional. The optional part is now done with the Partial type instead.

Sign up to request clarification or add additional context in comments.

Comments

0

I think what you are looking for can be achieved by the using overloads of the function. This will allow:

  1. To have a function with a single parameter.
  2. Inform the different types to the type system.
  3. Change the function behavior depending on the type you received. (This violate the OOP principle of Single responsibility, but let's go back to your question...)

So your function overloads would look something like this:

function doThingFunc(arg: { query: string, somthingElse?: string }): void;
function doThingFunc(arg: string): void
function doThingFunc(arg: any): void {
  if (typeof arg === 'object') {
    console.log(arg.query);
  }
  if (typeof arg === 'string') {
    console.log(arg);
  }
}
const doThing = doThingFunc;


doThing('some query');
doThing({ query: 'some query', somthingElse: 'something else' });

Of course, with this implementation you lose the this binding when used inside an object that arrow functions provide out of the box. More details here: https://www.typescriptlang.org/docs/handbook/functions.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.