No TypeScript com strict
habilitado ( TypeScript playground ):
type Foo = { a: number; b: number; }
class Bar {
#a?: Foo;
bar() {
const a = this.#a?.a;
if (!a) {return;}
// Error: Object is possibly 'undefined'.
const b = this.#a.b;
}
bar2() {
const obj = this.#getFoo();
const a = obj?.a;
if (!a) {return;}
// No error:
const b = obj.b;
console.log(b);
}
#getFoo() : Foo | undefined {
return undefined;
}
}
Por que TS entende corretamente que bar2()
isso obj.b
não pode ser undefined
; mas não this.#a.b
em bar()
? Existe um caso lógico que estou perdendo?
Em bar()
, se eu atribuir, const tmp = this.#a
ele também será compilado com sucesso.
ATUALIZAÇÃO: aparentemente tem algo a ver com a mutabilidade de uma variável. Se eu usar , o erro também let obj = this.#getFoo()
aparece .obj
O compilador ts não pode garantir que o
this.#a
valor não mudará entre os dois acessos de propriedade porque o TypeScript assume que o valor de uma propriedade de classe pode mudar a qualquer momento, mesmo entre duas linhas consecutivas de código, ou seja, o TypeScript não pode ter certeza de que o valor dethis.#a
permanece o mesmo entre as duas linhas.No
bar2()
método, o valor de obj é atribuído ao resultado dethis.#getFoo()
, que é uma variável local. O TypeScript pode garantir que o valor de obj não mudará entre os dois acessos de propriedade, por isso não reclama.Na sua última atualização , quando você usa
let obj = this.#getFoo()
, o TypeScript assume que o valor de obj pode potencialmente mudar entre os dois acessos de propriedade, uma vez que é mutável .obj
Como resultado, o erro também aparece .Agora, para corrigir o problema, você pode atribuir
this.#a
uma variável constante local . Algo como:PLAYGROUND TYPESCRIPT
Referências de contexto