Ошибка 2349 при работе с типом объединения generi c T и функции - PullRequest
2 голосов
/ 21 июня 2020

Как исправить приведенный ниже код для решения 2349?

function fillArray<T>(arr: T[], value: T | ((index: number) => T)): void {
    if (typeof value === 'function') {
        for (let i = 0; i < arr.length; i++) {
            arr[i] = value(i)
        }
    } else {
        arr.fill(value)
    }
}

Ошибка отчета TypeScript для value(i) как:

Это выражение не вызывается. Не все составляющие типа '((index: number) => T) | (T & Функция) 'вызываются.

См .: Ссылка на игровую площадку

1 Ответ

2 голосов
/ 21 июня 2020

Не уверен, что именно вызывает ошибку (может быть связано с этой проблемой с сужением параметров типа generi c).

В качестве обходного пути вы можете определить и использовать ограждение нестандартного типа :

function isFunction<T>(value: T | ((index: number) => T)): value is (index: number) => T {
    return typeof value === 'function';
}
    
function fillArray<T>(arr: T[], value: T | ((index: number) => T)): void {
    if (isFunction(value)) {
        for (let i = 0; i < arr.length; i++) {
            arr[i] = value(i)
        }
    } else {
        arr.fill(value)
    }
}

Детская площадка

Другой рабочий вариант, обнаруженный @VLAZ, использует instanceof охранник вместо typeof:

function fillArray<T>(arr: T[], value: T | ((index: number) => T)): void {
    if (value instanceof Function) {
        for (let i = 0; i < arr.length; i++) {
            arr[i] = value(i)
        }
    } else {
        arr.fill(value)
    }
}

Игровая площадка

Еще один рабочий вариант - сделать тип массива универсальным c параметром:

function fillArray<A extends Array<unknown>>(
    arr: A,
    value: A[number] | ((index: number) => A[number])
): void {
    if (typeof value === 'function') {
        for (let i = 0; i < arr.length; i++) {
            arr[i] = value(i)
        }
    } else {
        arr.fill(value)
    }
}

Площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...