TypeScript несколько возвращаемых типов с одинаковыми параметрами

фон

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

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

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any { /*common logic*/ };

Я знаю, что я могу верните один тип (например, обещание), который может быть нескольких подвидов:

private active(): Promise<void|null> { ... }

однако в контексте пользовательских валидаторов формы angular2 одна подпись (один параметр типа FormControl) может возвращать два разных типа: AN Object с ошибками формы, или null чтобы указать, что элемент управления не имеет ошибок.

это, очевидно, не работает:

private lowercaseValidator(c: FormControl): null;
private lowercaseValidator(c: FormControl): Object {
    return /[a-z]/g.test(c.value) ? null : { lowercase: this.validationMessages.lowercase };
}

ни

private lowercaseValidator(c: FormControl): null|Object {...}
private lowercaseValidator(c: FormControl): <null|Object> {...}

(интересно, я получаю следующие ошибки, а не что-то более информативное:

error TS1110: Type expected.
error TS1005: ':' expected.
error TS1005: ',' expected.
error TS1128: Declaration or statement expected.

)

TL; DR

я остался просто с помощью

private lowercaseValidator(c: FormControl): any { ... }

что, по-видимому, отрицает преимущество наличия сигнатур типов?

в целом, с нетерпением ждем ES6

хотя этот вопрос вдохновлен валидаторами форм angular2, которые обрабатываются непосредственно Платформой, поэтому вы можете не заботиться об объявлении возвращаемого типа, это все еще общеприменимо, особенно учитывая конструкции ES6, такие как function (a, b, ...others) {}

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

ссылки

1 ответов


Ok, это правильный путь, если вы хотите иметь правильные типы:

type CustomType = { lowercase: TypeOfTheProperty };
// Sorry I cannot deduce type of this.validationMessages.lowercase,
// I would have to see the whole class. I guess it's something
// like Array<string> or string, but I'm not Angular guy, just guessing.

private lowercaseValidator(c: FormControl): CustomType | null {
    return /[a-z]/g.test(c.value) ? null : { lowercase: this.validationMessages.lowercase };
}

более общий пример

type CustomType = { lowercase: Array<string> };

class A {
      private obj: Array<string>;

      constructor() {
            this.obj = Array<string>();
            this.obj.push("apple");
            this.obj.push("bread");
      }

      public testMethod(b: boolean): CustomType | null {
            return b ? null : { lowercase: this.obj };
      }
}

let a = new A();
let customObj: CustomType | null = a.testMethod(false);
// If you're using strictNullChecks, you must write both CustomType and null
// If you're not CustomType is sufficiant