TypeScript - 'this'默认为'any'

时间:2016-08-18 22:07:03

标签: typescript

有人可以解释为什么我没有在'this'变量的'setItem'函数中获得intellisense。我的理解应该是'_storageAdapter'属性?

class TestClass {
private testOne = () => {
}

_storageAdapter: {
    toType: (obj: any) => string,
    getItem: (key: string) => void,
    setItem: (key: string, value: string) => void,
}
= {
    toType: (obj: any) => {
        return "hello";
    },
    getItem: (key: string) => {
        this.testOne() // this is class scoped;
    },
    setItem: function (key: string, value: any) {
        this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any'
    }
}

}

2 个答案:

答案 0 :(得分:2)

常规js函数不保存this的范围,例如:

class A {
    obj = {
        withoutScope: function() {
            console.log(this);
        },

        withScope: () => {
            console.log(this);
        }
    }
}

编译成:

var A = (function () {
    function A() {
        var _this = this;
        this.obj = {
            withoutScope: function () {
                console.log(this);
            },
            withScope: function () {
                console.log(_this);
            }
        };
    }
    return A;
}());

注意两个console.log之间的区别:withoutScopethiswithScope_this(上面定义为var _this = this )。
这就是typescript编译器转换arrow function的方式,但是如果用ES6目标编译它,那么它会将它保持为箭头函数而不使用_this = this技巧,但结果将是同样的。

如果你打电话给那些方法:

let a = new A();
a.obj.withoutScope(); // Object {}
a.obj.withScope(); // A { obj: Object }

code in playground

在你的例子中也是如此,前两个函数是箭头函数,它们保持this的正确范围,但第三个函数没有。 您也可以在那里使用箭头功能,也可以使用Function.prototype.bind功能:

setItem: function (key: string, value: any) {
    this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any'
}.bind(this)

但它可能只会在运行时帮助你,因为我不确定你的intellisense会得到它。

答案 1 :(得分:1)

简化样本:

class TestClass {
    private testOne = () => {
    }

    _storageAdapter: {
        getItem: (key: string) => void,
        setItem: (key: string, value: string) => void,
    }
    = {
        getItem: (key: string) => {
            this.testOne() // this is class scoped;
        },
        setItem: function (key: string, value: any) {
            this.somethingThatDoesNotExist(); // this should be property scoped? but no intellisense? its just set to 'any'
        }
    }
}

原因是function没有捕获this,它实际上取决于函数的用户如何调用它。

箭头功能捕获this因此打字稿具有更强的保证。

更多

一些标志会阻止您措手不及:noImplicitAny https://basarat.gitbooks.io/typescript/content/docs/options/noImplicitAny.html