Typescript: нет ошибки для перегруженных методов с разными типами возвращаемых значений - PullRequest
0 голосов
/ 22 мая 2018

Надеюсь, этот заголовок достаточно объясняет ситуацию, с которой я пытаюсь справиться!Недавно я пытался создать интерфейс для метода, который мог бы принимать или параметр обратного вызова или , возвращающий обещание.Это было сделано для того, чтобы не вводить шаблон, основанный на Promise, в унаследованную часть кодовой базы, которая использовала только обратные вызовы.

Вот пример интерфейса, который я определил, и реализация этого интерфейса:

interface ITest {
    get(callback: () => void): void;

    get(): Promise<void>;
}


class Test implements ITest {
    public get(callback?: () => void): Promise<void> {
        if (typeof callback === 'function') {
            callback();
            return;
        }
        return Promise.resolve();
    }
}

Это, похоже, сработало, однако была ситуация, которая не была обработана:

const t = new Test();
// Good
t.get(() => console.log('callback'));
// Good
t.get().then(() => console.log('then'));
// Bad - Exception
t.get(() => console.log('callback')).then(() => console.log('then'));

Я надеялся, что в этом последнем примере Typescript будет жаловаться, что не было подписи дляфункция, которая приняла обратный вызов и вернула обещание.Однако, если я внесу приведенную ниже настройку, TypeScript действительно пожаловался:

const t: ITest = new Test();

С этим изменением последний пример вызвал ошибку TSC.Я понимаю, почему это так, как я прямо говорю, t реализует ITest.Тем не менее, я вижу, что это то, что я очень легко забываю сделать.

Итак, вопрос в том, есть ли лучший способ выполнить то, что я надеюсь сделать?

РЕДАКТИРОВАТЬ: Очень быстро получил ответ, отмеченный ниже!Если вам интересно, как выглядит «скомпилированный» класс с использованием этого ответа:

var Test = /** @class */ (function () {
    function Test() {
    }
    Test.prototype.get = function (callback) {
        if (typeof callback === 'function') {
            callback();
            return;
        }
        return Promise.resolve();
    };
    return Test;
}());

В конце концов, я не знал, что Typescript разрешит и удалит эти дополнительные объявления метода.Я мог видеть необходимость добавить некоторые дополнительные комментарии в мой код, чтобы объяснить кому-то незнакомому - как я был несколько минут назад - зачем нужны эти дополнительные объявления.

1 Ответ

0 голосов
/ 22 мая 2018

Вам нужно явно указать две перегрузки, чтобы получить тип ошибки, которую вы хотите.Проблема в том, что хотя метод get в классе реализует метод в интерфейсе (он удовлетворяет ограничениям), когда проверяется подпись функции в классе.Вы можете указать две перегрузки в явном виде, и сигнатура реализации (которая существует в настоящее время) будет скрыта извне.

interface ITest {
    get(callback: () => void): void;

    get(): Promise<void>;
}


class Test implements ITest {

    public get(callback: () => void): void;
    public get(): Promise<void>;
    public get(callback?: () => void): Promise<void> {
        if (typeof callback === 'function') {
            callback();
            return;
        }
        return Promise.resolve();
    }
}

const t = new Test();
// Good
t.get(() => console.log('callback'));
// Good
t.get().then(() => console.log('then'));
// Compile time error
t.get(() => console.log('callback')).then(() => console.log('then'));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...