Why does TypeScript enforce Get/Set accessors to have the same type? Let's say I want to have a property which returns a promise.
module App {
export interface MyInterface {
foo: ng.IPromise<IStuff>;
}
export interface IStuff {
bar: string;
baz: number;
}
class MyClass implements MyInterface {
private _fooDeferred: ng.IDeferred<IStuff>;
constructor(private $q: ng.IQService) {
this._fooDeferred = this.$q.defer();
}
get foo(): ng.IPromise<IStuff> {
return this._fooDeferred.promise;
}
set foo(value: IStuff) {
this._fooDeferred.resolve(value);
}
}
}
'Get' and 'Set' accessor must have the same type will be the error message coming from TypeScript.
The fix would be to type the accessors to any, but then we are losing the advantages of static typing, and might as well just write JS.
get foo(): any {
return this._fooDeferred.promise;
}
set foo(value: any) {
this._fooDeferred.resolve(value);
}
This sounds like a perfect opportunity to use a union type (TypeScript 1.4 or above) - example taken from this blog post:
type StringPromise = string | ng.IPromise<string>;
module App {
export interface MyInterface {
foo: ng.IPromise<string>;
}
class MyClass implements MyInterface {
private _fooDeferred: ng.IDeferred<string>;
constructor(private $q: ng.IQService) {
this._fooDeferred = this.$q.defer();
}
get foo(): StringPromise {
return this._fooDeferred.promise;
}
set foo(value: StringPromise) {
this._fooDeferred.resolve(value);
}
}
}
Notes:
Here is an example of a type guard
if (typeof value === 'string') {
// the type of value inside this if statement is
// string, rather than StringPromise
} else {
// the type of value inside this else statement is
// ng.IPromise<string>, rather than StringPromise
}
If needed, you can assert types like this:
var prom = <string> value;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With