question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Typescript type assertion for private Instance class variables

See original GitHub issue

Bug Report

Unable to type assert a private class variable instance

🔎 Search Terms

assertion

⏯ Playground Link

Playground link with relevant code Playground link 2

💻 Code

export class A {
  private myArray: string[] | undefined;

  private constructor() {}

  private assertMyArray(): asserts this is this & {
    myArray: string[]
  } {
    if (!this.myArray) throw new Error('myArray is not defined');
  }

  private doSomething() {
    this.assertMyArray();
    const len = this.myArray.length; // <-- error here
  }
}

🙁 Actual behaviour

TS evaluates the type assertion assertMyArray as never

TS2339: Property 'myArray' does not exist on type 'never'.   
The intersection 'this & { myArray: string; }' was reduced to 'never' because property 'myArray' exists in multiple constituents and is private in some.

If changing from private to public signature everything will work as expected

🙂 Expected behaviour

I think the expected behaviour should be exactly as on public variables, so it would evaluate correctly and not resolve the assertion to never (while keeping the right this type)

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
fatcerberuscommented, Jun 28, 2022

there’s no way to refer to the name of a private field in a way that creates the same kind of name as exists in the originating declaration.

To clarify on this potentially confusing point, what’s meant by this is that the “name” of a private property—for the purpose of structural typing—conceptually includes the identity of its containing class; in other words:

class A { private foo: string; }
class B { private foo: string; }

The usual typing model in TS is one where types are matched structurally according to the names of their properties, but under this model foo in A cannot be considered to have the same “name” as the foo in B because they originate from separate class definitions. Thus A and B are not assignable to each other.

The root of this issue is that there’s no way to construct a type on-the-fly that includes the requisite “foo originates from A” tag that would make the intersection method in the OP work.

1reaction
RyanCavanaughcommented, Jun 28, 2022

Someone more clever might be able to figure this out, but AFAICT there is no way to do this because there’s no way to refer to the name of a private field in a way that creates the same kind of name as exists in the originating declaration.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript: Documentation - Classes
TypeScript offers full support for the class keyword introduced in ES2015. As with other JavaScript language features, TypeScript adds type annotations and ...
Read more >
TypeScript Data Modifiers: public, private, protected, static, ...
Learn about data modifiers in TypeScript. There are three types of access modifiers in TypeScript: public, private and protected.
Read more >
Is it possible to persist type assertion of a variable, or have ...
You can persist the type assertion of a variable, but not of an object property (since that might get mutated in the meantime)....
Read more >
typescript-cheatsheet - GitHub Pages
The cheatsheet contains references to types, classes, decorators, ... class OnlyOne { private static instance: OnlyOne; // Member variable that will store ...
Read more >
Interfaces
The easiest method is to just use a type assertion: ... them to check that a class also has particular types for the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found