Перегрузка метода Typescript одним параметром другого типа (не примитив)

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

Я понимаю, что не могу сделать это так, потому что TypeScript теряет все типы при компиляции в JavaScript. Если бы один из параметров был примитивным (например, строка), я мог бы это сделать (typeof myString == "string").

public doSomething(typeA: TypeA);
public doSomething(typeB: TypeB);
public doSomething(type: TypeA | TypeB) {
    if (typeof type == "TypeA") {
        ... // obviously I can't do that, Javascript got no types
        ... // typeof type === "object"
    }
    else if (typeof type == "TypeB") { //the same }
    else { //undefined }
}

Что я придумал, так это:

public doSomething(typeA?: TypeA, typeB?: TypeB) {
    if (typeA) { ... }
    else if (typeB) { ... }
    else { //undefined }
}

Тогда я должен назвать это так:

doSomething(typeA, undefined); //to call TypeA version
doSomething(undefined, typeB); //to call TypeB version

Является ли такой дизайн приемлемым или лучше создать два отдельных метода?

РЕДАКТИРОВАТЬ:

Эта запись, вероятно, лучше. Вы вынуждены (в IDE) добавлять неопределенное при вызове метода.

public doSomething(typeA: TypeA | undefined, typeB: TypeB | undefined) {
    if (typeA) { ... }
    else if (typeB) { ... }
    else { //undefined }
}

1 ответ

Решение

У вас могут быть функции, которые проверяют, относится ли значение к определенному типу, а в машинописном тексте есть понятие охранников определяемых пользователем типов:

interface TypeA {
    x: string;
}
function isTypeA(value: any): value is TypeA {
    return Object.keys(value).length === 1 && typeof value.x === "string";
}

interface TypeB {
    y: number;
}
function isTypeB(value: any): value is TypeB {
    return Object.keys(value).length === 1 && typeof value.y === "number";
}

function doSomething(typeA: TypeA);
function doSomething(typeB: TypeB);
function doSomething(type: TypeA | TypeB) {
    if (isTypeA(type)) {
        console.log(type.x);
    } else {
        console.log(type.y);
    }
}

( код на детской площадке)

В вашем примере в качестве переданного значения может быть только TypeA а также TypeB тогда нет необходимости в дополнительном if/else.
Но вы также можете использовать isTypeB,

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

Другие вопросы по тегам