1

I have existing API that I thinking to add type to, and I have function that accept string function or object (I can use overloading for this) but it also accept array of mixed values like these.

Is it possible to have Array of strings, functions or plain objects in TypeScript? It should throw error for array with other types.

EDIT based on comments I added this:

function Terminal(interpreter: (string, object) => void, settings: object);
function Terminal(interpreter: (string | ((string, object) => void) | object)[], settings: object) {
    if (typeof interpreter == 'function') {
        interpreter("foo", {});
    } else if (interpreter instanceof Array) {
        interpreter.forEach((arg) => console.log(arg));
    }
}

Terminal(["foo", function (command, term) { }], {});
Terminal(function(command) {

}, {});

but got error in TypeScript playground about overload signature don't match implementation and one from invocation.

13
  • 6
    Yes, it's possible: (string | Function | object)[] Commented Jun 11, 2018 at 7:11
  • 2
    or string[] | Function[] | object[] Commented Jun 11, 2018 at 7:12
  • Possible duplicate of Typing an Array with a union type in TypeScript? Commented Jun 11, 2018 at 7:17
  • Mixed-type arrays are generally poor design. Objects are better for this case in most cases. Commented Mar 23, 2023 at 18:03
  • @ggorlen in my case, it's not poor design, thanks for your comment completely not related to the question. Commented Mar 23, 2023 at 20:31

1 Answer 1

4

If you use union type, you have to list all possible argument types in that union type. If you say

function that accept string function or object (I can use overloading for this) but it also accept array of mixed values like these

you can define type alias for a single value that can be string, function or object

type SingleArg = string | object | ((string, object) => void);

and define a function that takes one SingleArg or array (you don't need to have any overloads)

function Terminal(interpreter:  SingleArg | SingleArg[], settings: object) {
    if (typeof interpreter == 'function') {
        interpreter("foo", {});
    } else if (interpreter instanceof Array) {
        interpreter.forEach((arg) => console.log(arg));
    }
}

Terminal(["foo", function (command, term) { }], {});
Terminal(function(command) {

}, {});

The other restriction

It should throw error for array with other types.

is tricky because for example numbers are objects in TypeScript. To be able to disallow numbers, but not objects, you have to be more specific about the exact kind of the objects that should be accepted.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.