打字稿错误:“this”的外部值被此容器遮挡

问题描述 投票:0回答:5

我在 Typescript 类方法声明中遇到错误,但我不明白错误消息如何与错误相关联。

该消息似乎是在说“this”是

any
类型,但我们处于类定义中,所以我认为“this”非常清楚。

有人可以解释一下错误消息与错误有何关联吗?

原始方法:

calcSize = function() {
    return this.width * this.length; // Error on this line
};

// Error text: 'this' implicitly has type 'any' because it does not 
//have a type annotation.ts(2683)
//app.ts(39, 16): An outer value of 'this' is shadowed by this container.

修复:

calcSize() {
    return this.width * this.length;
};

完整上下文(已修复):

class BaseObject {
    constructor(
        public width: number = 0,
        public length: number = 0
        ) {}

};

class Rectangle extends BaseObject {

    constructor(public width: number = 0, public length: number = 0) {
        super(width, length);
    }

    calcSize() {
        return this.width * this.length;
    };
}
typescript class oop
5个回答
70
投票

在 TypeScript(和 ES6)中存在两种函数:经典的 function 声明和 arrow function。经典函数声明具有

this
关键字的默认浮动绑定逻辑 - 箭头函数将不断使用包含箭头函数的上下文的
this
的值。在示例中,这将是周围类的实例。

class Rectangle extends BaseObject {
  // ..
  calcSize = function() {
    // The keyword "function" will cause "this" to be floating.
    // Since the function is explicitly assigned to calcSize
    // (older) TypeScript may not infer the type of "this".
    // The value of "this" can be re-bound by changing the context
    // using bind or call.
    // -> Value of "this" defaults to the class instance
    return this.width * this.length; // (potential) type Error on this line
  };

  calcSizeAsMember () {
    // This is also a classic function which will use floating binding
    // therefore "this" will be the type of the containing class.
    // The value of "this" can be re-bound by changing the context
    // using bind or call.
    // -> Value of "this" defaults to the class instance
    return this.width * this.length; 
  };

  calcSizeAsArrowFunction = () => {
    // This is an arrow function which has a constantly-bound "this" keyword, 
    // it is not possible to re-bind afterward.
    // The type of "this" is always the type of the containing class.
    // Changing the context using bind or call will have no effect
    // -> Value of "this" is always the class instance
    return this.width * this.length;
  };

};

10
投票

经过一些研究,我发现了一些有趣的事情。 “this”可以是常规函数(不是箭头函数)的参数,类型可以是“any”或“unknown”

声明函数时,请注意“this”的类型为“any”。

export async function main(this: any) {
    try {
        console.log(this);
    } catch (e: any) {

    }
}

0
投票

对于任何明确想要从非类函数访问类属性的人。您可以像下面这样解决问题:

calcSize = function(this: Rectangle) {
    return this.width * this.length; // Error on this line
};

这将传递对象并且类型安全。


0
投票

只是把我的答案放在这里。看起来打字稿解析器已更新。以前这有效。但看起来声明

@this
after 声明可选参数现在会破坏分析器。

/**
 * @param {object} [foo]
 * @param {string} [foo.bar]
 * @this {MyType}
 */
 function foobar({bar = 'default bar'} = {}) {...}

上面的方法曾经有效,但分析器开始抱怨它。直到我将

@type
声明移动到 jsdoc 注释的顶部,它才再次开始工作(在可选参数之前)


-12
投票

用 setTimeout 上的箭头函数来实现

setTimeout(() => {
  yourFunction()
}, 3000);
© www.soinside.com 2019 - 2024. All rights reserved.