jcubic
jcubic

Reputation: 66488

Array for mixed types in TypeScript

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.

Upvotes: 1

Views: 7257

Answers (1)

artem
artem

Reputation: 51609

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.

Upvotes: 4

Related Questions