web-dev-qa-db-ja.com

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*/ };
_

itselfが複数のサブタイプである単一のタイプ(Promiseなど)を返すことができることも知っています。

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

ただし、angular2カスタムフォームバリデーターのコンテキストでは、単一のシグネチャ(タイプFormControlの1つのパラメーター)が2つの異なるタイプを返すことがあります。フォームエラーのある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フォームバリデーターに触発されているため、戻り値の型を宣言する必要はないかもしれませんが、特にfunction (a, b, ...others) {}

おそらく、複数の型を返すことができる関数を書くことを避ける方が良い習慣かもしれませんが、JavaScriptの動的な性質のため、それはかなり慣用的です。

参考文献

12
msanford

さて、あなたが適切なタイプを持ちたいなら、これは正しい方法です:

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
9
Erik Cupal