TypeScript multiple return types with the same parameters

Background

Trying to get into the spirit of TypeScript, I write fully typed signatures in my Components and Services that extend to my custom validation functions for angular2 forms.

I know that I can overload the function signature , but this requires that the parameters be different for each return type, because tsc compiles each signature to a separate function:

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

I also know that I can return one type (for example, Promise), which itself can be from several subtypes:

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

However, in the context of custom form angular2 validators, one signature (one parameter of type FormControl ) can return two different types: Object with form errors or null to indicate a control has no errors.

This obviously does not work:

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

Don't do

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

(Interestingly, I am getting the following errors, and not something more informative:

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

)

TL DR

It remains just to use

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

which would seem to deny the advantage of having type signatures?

More generally, I look forward to ES6

While this question is inspired by angular2 form validators that are handled directly by the framework, so you might not like the return type declaration, it is still generally applicable, especially considering ES6 constructs like function (a, b, ...others) {}

It might just be better to avoid writing functions that can return multiple types, but this is pretty idiomatic due to the dynamic nature of JavaScript.

References

+5
source share
1 answer

Ok, this is the right way if you want to have the appropriate types:

 type CustomType = { lowercase: TypeOfTheProperty }; // Sorry I cannot deduce type of this.validationMessages.lowercase, // I would have to see the whole class. I guess it something // like Array<string> or string, but I'm not Angular guy, just guessing. private lowercaseValidator(c: FormControl): CustomType | null { return /[az]/g.test(c.value) ? null : { lowercase: this.validationMessages.lowercase }; } 

More general example

 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 
+6
source

Source: https://habr.com/ru/post/1258752/


All Articles