【问题标题】:TypeScript properties returning a promise - Get/Set accessors must have the same type返回 Promise 的 TypeScript 属性 - Get/Set 访问器必须具有相同的类型
【发布时间】:2015-04-04 10:46:13
【问题描述】:

为什么 TypeScript 强制 Get/Set 访问器具有相同的类型? 假设我想要一个返回承诺的属性。

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' 和 'Set' 访问器必须具有相同的类型将是来自 TypeScript 的错误消息。

解决方法是将访问器键入 any,但这样我们就失去了静态类型的优势,还不如只写 JS。

        get foo(): any {
            return this._fooDeferred.promise;
        }

        set foo(value: any) {
            this._fooDeferred.resolve(value);
        }

【问题讨论】:

  • 真的想要一个类,其中在读取和写入时属性具有不同的类型?这似乎是对 getter/setter 的滥用。
  • 瑞恩,这是我的问题。否则您将如何拥有一个返回承诺的属性?下面史蒂夫芬顿的回答似乎是合理的。
  • 由于已解决的承诺不应该被多次解决,即使使用 Steve Fenton 的实现,您也需要防止多次设置属性。

标签: angularjs typescript


【解决方案1】:

这听起来像是使用联合类型(TypeScript 1.4 或更高版本)的绝佳机会 - 示例取自 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);
        }
    }
}

注意事项:

  • 当您想使用联合类型中的特定类型时,您需要使用类型保护
  • 在某些情况下您可能需要使用类型断言

类型保护

这是一个类型保护的例子

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
}

类型断言

如果需要,您可以这样断言类型:

var prom = <string> value;

【讨论】:

  • 类型保护/断言的一个复杂情况是,如果类型是接口而不是原始类型。我会更新我的问题以反映这一点。
猜你喜欢
  • 1970-01-01
  • 2022-09-30
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多