如何在Typescript接口文件中表示返回类型?

时间:2015-12-16 10:52:50

标签: javascript typescript

以下代码之间有什么区别:

changeName(): ng.IPromise<any>;

changeName: () => ng.IPromise<any>;

我理解一个是返回类型,但我对第一个感到困惑。

这是函数体:

changeName = (): ng.IPromise<any> => {
        var self = this;
        self.chnAction = "PREFERENCES.CHANGE_NAME.SUBMITTING_BUTTON_TEXT";
        self.chnErrorMessage = null;
        return self.uss.changeName(
            self.chnNewFirstName,
            self.chnNewLastName)
            .then(
            (response: ng.IHttpPromiseCallbackArg<any>): any => {
                self.chnAction = "PREFERENCES.CHANGE_NAME.SUBMITTED_BUTTON_TEXT";
                self.chnNewFirstName = '';
                self.chnNewLastName = '';
                self.chnErrorMessage = null;
                self.logout();
                return this.$state.go('home.auth', { content: 'change_name_success' });
            },
            (error: ng.IHttpPromiseCallbackArg<any>): ng.IPromise<any> => {
                if (error.status === 500) {
                    self.chnErrorMessage = 'AUTH_SERVICE.UNABLE_TO_CONTACT_SERVER';
                } else {
                    var errors: string[] = [];
                    Object.keys(error.data.modelState).forEach((key) => {
                        errors.push.apply(errors, error.data.modelState[key]);
                    });
                    self.chnErrorMessage = errors[0];
                    self.chnErrorMessages = errors;
                    self.chnAction = "PREFERENCES.CHANGE_NAME.SUBMIT_BUTTON_TEXT";
                }
                return this.$q.reject(error);
            });
    };

4 个答案:

答案 0 :(得分:4)

根本区别在于:

  • changeName(): ng.IPromise<any>;代表方法
  • changeName: () => ng.IPromise<any>;表示可以保存函数的属性(这与changeName = (): ng.IPromise<any> => { ... };匹配,因为它正在为属性分配函数。)

因此,属性和方法之间的差异适用。这是一个例子:

interface MyInterface {
    myMethod(): string;
    myProperty: () => string;
}

class MyBaseClass implements MyInterface {
    myMethod() {
        return "string";
    }

    myProperty = () => "string";
}

class MyChildClass extends MyBaseClass {
    myMethod() {
        return super.myMethod();
    }

    myProperty = () => super.myProperty(); // error
}

有时使用箭头函数属性而不是方法的原因是因为分配给属性的箭头函数保留this的值,无论它绑定到什么...

class MyClass {
    myMethod() {
        console.log(this);
    }

    myProperty = () => console.log(this);
}

new MyClass().myMethod.call({});   // outputs {}
new MyClass().myProperty.call({}); // outputs the instance of MyClass

...因为this的值保留在构造函数中......

var MyClass = (function () {
    function MyClass() {
        // captures this here
        var _this = this;
        // guaranteed to always use instance of class for `this`
        this.myProperty = function () { return console.log(_this); };
    }
    MyClass.prototype.myMethod = function () {
        // not guarnateed to always use instance of class
        console.log(this);
    };
    return MyClass;
})();

Sidenote :您可以在JS here中阅读.call

答案 1 :(得分:2)

最好显示整个代码示例。希望以下示例将解释您的问题:

class MyClass {

    changeName(): number {
        return 5;
    }

    changeName2 = ():number => {
        return 5;
    }
}

转换为:

var MyClass = (function () {
    function MyClass() {
        this.changeName2 = function () {
            return 5;
        };
    }
    MyClass.prototype.changeName = function () {
        return 5;
    };
    return MyClass;
})();

[Playground]

Declaring javascript object method in constructor function vs. in prototype

中对这两个定义之间的差异进行了深入的解释

答案 2 :(得分:2)

界面上没有区别。这是一个使用两种符号的接口(为了清楚起见,我们使用string作为返回类型):

interface MyInterface {
    foo(): string; // preferred
    bar: () => string;
}

此处,foo是返回类型为string的函数。 bar的类型也是返回类型string的函数。第一种表示法通常更清晰。以下对象与接口匹配:

let x: MyInterface = {
    foo: () => "",
    bar: () => ""
}

上,一个表示法是将函数添加到原型中,而另一个表示法则将其添加为新实例(this.myFunc = ...)的属性。这与JavaScript中的效果完全相同(您几乎不需要将函数/方法添加为实例属性)。

class MyClass {
    bar(): string { return ""; } // prototype, preferred
    foo = () => ""; // instance property
}

正如我们在下面看到的那样,即使我推翻foobar,该类也适合我们的原始界面。因此,接口不会强制设置方法的实现细节。

let y: MyInterface = new MyClass();

请注意,类不是特殊类型 - 它实际上是一个接口和一个实现。因此,您可以像使用任何其他类型(无论是定义为接口还是类)一样使用MyClass

let z: MyClass = {
    foo: () => "",
    bar: () => ""
}

关于类型(接口定义的类型),没有区别,尽管在类中使用时,符号会产生不同的实现。

答案 3 :(得分:1)

以下代码

之间的区别是什么

因为您没有添加更多代码来查看实际配置的内容。我可以看到你有两行代码:

changeName(): ng.IPromise<any>;

根据此代码,人们可以理解它返回的类型为any的承诺,可以是任何内容,object, string, array, number等。

因此,可以说changeName()将返回ng.IPromise类型<any>的值。

另一行代码:

changeName: () => ng.IPromise<any>;

表示此函数将返回ng.IPromise事物的值<any>