Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private and protected modifiers are removed without error in declaration emit if class expression is passed through a generic function #42499

Closed
dragomirtitian opened this issue Jan 26, 2021 · 2 comments Β· Fixed by #42585
Assignees
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status.

Comments

@dragomirtitian
Copy link
Contributor

dragomirtitian commented Jan 26, 2021

Bug Report

πŸ”Ž Search Terms

class expressions private protected declaration
mixins private protected declaration

πŸ•— Version & Regression Information:

  • This is the behavior in every version I tried 3.3 - 4.2@beta

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

declare function mix<TMix>(mixin: TMix): TMix;

const DisposableMixin = class {
    protected _onDispose() {
        this._assertIsStripped()
    }
    private _assertIsStripped() {
    }
};

// Expected error since declaration is not representable 
// export const DisposableMixinError =  mix(DisposableMixin);

// No error, but definition is wrong. 
export default mix(DisposableMixin);
export class Monitor extends mix(DisposableMixin) {
    protected _onDispose() {
    }
}

πŸ™ Actual behavior

Emitted declaration erases private and protected modifiers on DisposableMixin. This actually generates a ts error in the declaration of Monitor on the _onDispose override, since the method has a more restrictive modifier than the emitted declaration for the base class.

declare const _default: {
    new (): {
        _onDispose(): void;
        _assertIsStripped(): void;
    };
};
export default _default;
declare const Monitor_base: {
    new (): {
        _onDispose(): void;
        _assertIsStripped(): void;
    };
};
export declare class Monitor extends Monitor_base {
    protected _onDispose(): void;
}

Playground Link

πŸ™‚ Expected behavior

An error on the exported private and protected members (like what happens if you uncomment DisposableMixinError ):

Property '_onDispose' of exported class expression may not be private or protected.(4094)
Property '_assertIsStripped' of exported class expression may not be private or protected.(4094)

Note

This issue might be made moot by #41581 in 4.3, or later, depending when declaration emit will be changed to use typeof class

@MartinJohns
Copy link
Contributor

#36060

@dragomirtitian
Copy link
Contributor Author

dragomirtitian commented Jan 26, 2021

@MartinJohns I agree that issue is related and I did find it. But this issue is specifically about the absence of the error the other issue is complaining about. If private and protected are forbidden in exported class expressions this should be uniformly enforced.

The fact that it isn't uniformly enforced causes some code of ours to fail when using the emitted declarations, even though they are emitted from error free code.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jan 29, 2021
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.3.0 milestone Jan 29, 2021
@typescript-bot typescript-bot added the Fix Available A PR has been opened for this issue label Feb 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
5 participants