打字稿错误:属性已分配使用

时间:2018-08-03 15:26:45

标签: typescript

打字稿显示 [ts]属性'logger'在VSCode中分配前已使用。错误发生在下面this.logger.logInfo(Important, ...的代码中。我非常清楚地将此属性设置在构造函数的第二行上,以便...?

如果我使用代码(self.logger.logInfo ...)中显示的self变量,则TS错误消失了,但这不是必须的。

感谢您分享您的专业知识:-)

// app/data/mongo/_base.data.mongo.ts 

import { MongoClient, ObjectId } from 'mongodb';
import { IBaseModel } from '../../model/_base.model';
import { Logger, Important, NotImportant } from '../../util/logger';

export default class BaseData {

    constructor(params: any) {
        this.collectionName = params.collectionName;
        this.logger = new Logger(this.collectionName);
        if (this.db) {
            this.collection = this.db.getCollection(this.collectionName);
        } else {
            BaseData.userId = params.user.id;
            BaseData.userHandle = params.user.handle;
            this.dbServer = params.dbServer;
            this.dbPort = params.dbPort || '27017';
            this.dbName = params.dbName;
            const self = this; // This is a Typescript BUG!
            (async () => {
                const url = `mongodb://${this.dbServer}:${this.dbPort}`;
                this.db = await MongoClient.connect(url, { "useNewUrlParser": true });
                this.collection = this.db.collection(this.collectionName);
                this.logger.logInfo(Important, 'contructor', `MongoDb connection (${url}) success!`);
            })();
        }
    }

    static userId: string;
    static userHandle: string;

    protected logger: Logger;
    protected collectionName: string = '';
    protected client: any;
    protected collection: any;
    protected db: any;
    protected dbServer: string = '';
    protected dbPort: string = '';
    protected dbName: string = '';

1 个答案:

答案 0 :(得分:4)

以下是一些完整的代码,可以重现此问题:

// Turn on --strictNullChecks and --strictPropertyInitialization
class Foo {
    prop: string;
    constructor() {
        this.prop = "assigned";
        (async () => {
            this.prop; // error, used before assigned
        })();
    }
}

View on the Playground(记住要打开--strictNullChecks--strictPropertyInitialization编译器选项)。


如果不是完全错误,这很可能是TypeScript中的设计限制。事实是,自动化控制流分析为hard to do "right"。由于编译器通常无法准确确定程序中每个点上每个变量可能具有的状态,因此它必须使用启发式方法,这往往会导致错误的否定(未捕获的错误)和错误的肯定(被捕获的非错误)。错误)。对我来说,这似乎是错误的肯定,因为在设置this.prop之后肯定会调用异步函数。 A similar issue之前已经提出并使用了 synchronous 立即调用的函数表达式。

我认为在这里需要权威地讲一些有关TypeScript如何控制流分析的细节的知识,但是我猜想这种特殊情况还没有被预料到或遇到来处理。如果您认为自己有一个引人注目的用例,则可以假设没有人对此问题提供更令人满意的答案,file an issue in GitHub

同时,如果您有一种解决方法,例如分配const self = this然后访问self.prop,或者等效地访问(this as this).prop,那么我猜您应该使用它。而且,所有解决方法中总会有大锤,//@ts-ignore comment

class Foo {
  prop: string;
  constructor() {
    this.prop = "assigned";
    (async () => {
      // @ts-ignore: this.prop is really assigned before being used
      this.prop;
    })();
  }
}

哦,对不起,我没有更好的消息。希望在任何情况下都能有所帮助。祝你好运!