Exploring TypeScript Signatures
In an effort to embrace TypeScript fully, I am implementing strongly typed signatures in my Components and Services, including custom validation functions for angular2 forms.
I have discovered that while function overloading is possible, each signature must have different parameters because tsc
compiles them into separate functions:
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any { /*common logic*/ };
Furthermore, I found that returning a single type like a Promise can also be versatile by supporting multiple sub-types:
private active(): Promise<void|null> { ... }
However, the challenge arises when dealing with angular2 custom form validators where a single parameter of type FormControl
can return either an Object
with errors or null
to signify no errors.
The traditional approaches do not work as expected:
private lowercaseValidator(c: FormControl): null;
private lowercaseValidator(c: FormControl): Object {
return /[a-z]/g.test(c.value) ? null : { lowercase: this.validationMessages.lowercase };
}
Consequently, using any
seems like a fallback option that undermines the benefits of having type signatures.
Future Perspective on ES6
This dilemma extends beyond just angular2 form validators to more general scenarios, especially considering upcoming ES6 features like rest parameters (function (a, b, ...others) {}
). While it may seem advisable to avoid functions returning multiple types, it remains a common practice given JavaScript's dynamic nature.
References
- TypeScript function overloading
- Typescript syntax for a function returning observable or multiple type
- https://github.com/Microsoft/TypeScript/issues/11700
- https://github.com/Microsoft/TypeScript/issues/10727
(...spread) {}
- https://github.com/Microsoft/TypeScript/issues/10571
< , , type>