Компилятору не удается развернуть тип (string[] | number[])
для вывода аргумента типа. В этом случае явно передается аргумент типа:
arrays.map(arr => myFunction<string | number>(arr));
Это один из тех случаев, когда компилятор обрабатывает:
(string | number)[][]
По-другому:
(string[] | number[])[]
Если вы используете последний, он выводит аргумент типа как string[]
, который затем не срабатывает для number[]
.
Вы можете помочь компилятору с защитой типа, но этот пример действительно продуманное упражнение, и я не могу представить себе желание использовать это в реальной жизни:
function isStringArray(arr: any[]): arr is string[] {
return (typeof arr[0] === 'string');
}
arrays.map(arr => (isStringArray(arr)) ? myFunction(arr) : myFunction(arr));
Даже при том, что он вызывает myFunction
в любом случае, он может вывести аргумент типа как string[]
и number[]
в каждом случае.
Самый легкий подход должен, вероятно, сохранить некоторое внешнее состояние и иметь реализацию влияния f, это - содержание.
(define x 0)
(define (f n) (let ((tmp x)) (set! x n) tmp))
Таким образом x первоначально 0, и каждый вызов к f возвратит текущее значение x и сохранит аргумент как новое значение x. Таким образом (f 0) сопровождаемый (f 1) оба возвратится 0, оставляя финал x значением 1. В то время как оценка (f 1), сопровождаемого (f 0), уступит 0 затем 1 с финалом x 0.
With call/cc.
(define (f)
(call/cc
(lambda (c) (+ (c 0) (c 1)))))
(write (f))
Invoking c within either argument to +
causes f
to return immediately, yielding 0 or 1 depending which argument is evaluated first.
But I suspect it will always evaluate left-to-right and thus return 0.