I think it'd be more useful if the whole tuple is repeated, rather than a function-style "many" argument at the end. I.e. like this:
array(int) -> Zero or more ints. array(string,int) -> Zero or more (string,int) tuples, i.e. the array always has an even number of elements.
Then there could be another extension to handle arrays of specified lengths. Something like this, perhaps:
array(int)(..1) -> Zero or one int but no more. array(string,int)(1..2) -> One or two (string,int) tuples, i.e. either two or four elements in total. array(int)(3) -> Perhaps a shortcut for array(int)(3..3).
This scheme wouldn't allow for specifying arrays where the first couple of elements have some specified types and all the rest have the same type, but I can't think of any real world cases where such typing would be useful. Theoretically it could be used when splicing arrays to function arguments. I've very rarely spliced arrays into arguments that were declared to different types, though; the whole array is typically spliced into the "many" argument at the end.