首页 > 解决方案 > 在 TypeScript 类中,是否有一种干净的方法来处理最初未定义的值?

问题描述

想象一个Connection使用密码实例化的类,用于从服务器获取令牌。所以

class Connection {
  password: string
  token?: string

  constructor(password: string) {
    this.password = password
  }

  async connect() {
    // ... connect to server
    this.token = await 'something that we get from the server'
  }

  doStuff() {
    // at this point I know that `this.token` is defined
    const something = someUtilityFunction(this.token)
    // this will fail because TypeScript still thinks this.token might be undefined
  }
}

function someUtilityFunction(token: string) {
  // this function requires `token` to be defined
}

// using the class:
const conn = new Connection('foo')
await conn.connect()
conn.doStuff()

我知道我可以断言this.token!.

class Connection {
  ...
  doStuff() {
    const something = someUtilityFunction(this.token!)
  }
}

我也可以在每个引用之前this.token加上一个断言函数

function assert(value: unknown): asserts value {
  if (value === undefined) throw new Error('must be defined');
}

...

class Connection {
  ...
  doStuff() {
    assert(this.token)
    const something = someUtilityFunction(this.token)
  }
}

this.token但是,在我余下的课堂生活中,每次提到这些都必须做这件事,感觉很混乱。

有没有更好的办法?

标签: typescript

解决方案


但是,在课堂的余生中,每次我提到 this.token 时都必须做这两个中的任何一个,感觉很混乱。

它并不凌乱。

可选的属性本质上总是可以未定义的,因此在您访问它时需要检查它。

解决方案 1:令牌根本不是可选的

class Connection {
  password: string
  token: string

  constructor(password: string) {
    this.password = password;
    this.token = '';
  }

如果您知道在匿名函数中this.token应该定义它,那么一开始就没有理由将其未定义。

解决方案 2:断言函数

function getToken(): string {
  if(this.token) return this.token;
  throw new Error(`Token is not defined`);
}

只需检查this.token使用它时定义的内容,您将只拥有if一次。


推荐阅读